Valkey Cluster Demo 
[acool@localhost ~]$ date
Fri Jul 5 01:48:53 PM PDT 2024
[acool@localhost ~]$ cat /etc/redhat-release
Fedora release 38 (Thirty Eight)
[acool@localhost ~]$ sudo dnf install valkey
...
[acool@localhost ~]$ valkey-cli --version
valkey-cli 7.2.4
[acool@localhost ~]$
[acool@localhost ~]$ # just in case...
[acool@localhost ~]$ systemctl stop valkey.service
[acool@localhost ~]$ systemctl status valkey.service
...
[acool@localhost ~]$ which valkey-server
/usr/bin/valkey-server
[acool@localhost ~]$
[acool@localhost ~]$ mkdir valkey-cluster-demo
[acool@localhost ~]$ cd valkey-cluster-demo/
[acool@localhost valkey-cluster-demo]$ vim valkey.conf
...
[acool@localhost valkey-cluster-demo]$ cat valkey.conf
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
[acool@localhost valkey-cluster-demo]$
[acool@localhost valkey-cluster-demo]$ mkdir cluster-test
[acool@localhost valkey-cluster-demo]$ cd cluster-test/
[acool@localhost cluster-test]$ mkdir -p {7000..7005}
[acool@localhost cluster-test]$ for i in {7000..7005}; do cp ../valkey.conf $i; done
[acool@localhost cluster-test]$ # open 7 tabs, update ports and start servers
[acool@localhost cluster-test]$ cd 7000/
[acool@localhost 7000]$ /usr/bin/valkey-server ./valkey.conf
...
[acool@localhost valkey-cluster-demo] # create cluster
[acool@localhost valkey-cluster-demo]$ valkey-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
...
[acool@localhost valkey-cluster-demo]$ valkey-cli -p 7000 cluster nodes
384d585df521f8588a03b57a38e871549c0e58c4 127.0.0.1:7001@17001 master - 0 1720214911355 2 connected 5461-10922
5d2edcbba8f394a612df5253bd19a9399f97f4ff 127.0.0.1:7002@17002 master - 0 1720214912358 3 connected 10923-16383
4cf4150f20ae444422f0dabbc29b0a75878b1a2d 127.0.0.1:7004@17004 slave c88d6bea070f64023a2c7f27831bbbd113b2ff03 0 1720214912000 1 connected
e40a58e318f277ce2d420f7cb77480d5643c28c4 127.0.0.1:7005@17005 slave 384d585df521f8588a03b57a38e871549c0e58c4 0 1720214913362 2 connected
c88d6bea070f64023a2c7f27831bbbd113b2ff03 127.0.0.1:7000@17000 myself,master - 0 1720214912000 1 connected 0-5460
5b13cd8e34b47890e88fb48e30a99174ba19b751 127.0.0.1:7003@17003 slave 5d2edcbba8f394a612df5253bd19a9399f97f4ff 0 1720214911354 3 connected
[acool@localhost valkey-cluster-demo]$
[acool@localhost valkey-cluster-demo]$
[acool@localhost valkey-cluster-demo]$ # To connect to Valkey Cluster, you'll need a cluster-aware Valkey client...
[acool@localhost valkey-cluster-demo]$ # ...store some keys
[acool@localhost valkey-cluster-demo]$ valkey-cli -c -p 7000
127.0.0.1:7000> set firstname Angel
-> Redirected to slot [7108] located at 127.0.0.1:7001
OK
127.0.0.1:7001> set lastname Cool
OK
127.0.0.1:7001>exit
[acool@localhost valkey-cluster-demo]$
[acool@localhost valkey-cluster-demo]$ # Retrive some keys
[acool@localhost valkey-cluster-demo]$ valkey-cli -c -p 7005
127.0.0.1:7005> get lastname
-> Redirected to slot [7726] located at 127.0.0.1:7001
"Cool"
127.0.0.1:7001> get firstname
"Angel"
127.0.0.1:7001>exit
[acool@localhost valkey-cluster-demo]$
[acool@localhost valkey-cluster-demo]$


Bonus: Pub/Sub demo

[acool@localhost valkey-cluster-demo]$ # TERMINAL 1
[acool@localhost valkey-cluster-demo]$ valkey-cli -c -p 7001
127.0.0.1:7001> SUBSCRIBE channel-a
...
[acool@localhost valkey-cluster-demo]$ # TERMINAL 2
[acool@localhost valkey-cluster-demo]$ valkey-cli -c -p 7002
127.0.0.1:7002> SUBSCRIBE channel-b
...

[acool@localhost valkey-cluster-demo]$ # TERMINAL 3
[acool@localhost valkey-cluster-demo]$ valkey-cli -c -p 7000
127.0.0.1:7000> PUBLISH channel-a "Hello channel a!"
(integer) 0
127.0.0.1:7000> PUBLISH channel-b "Hello channel b!"
(integer) 0
127.0.0.1:7000>
127.0.0.1:7000> exit
[acool@localhost valkey-cluster-demo]$ # Monitor output in TERMINAL 1 and 2


[ view entry ] ( 2 views )   |  print article
Elixir: Making Concurrent API Calls 
angelcool@fedora-laptop$
angelcool@fedora-laptop$date
Fri Apr 12 07:51:16 PM PDT 2024
angelcool@fedora-laptop$ls lib/
coolprogram.ex coordinator.ex worker.ex
angelcool@fedora-laptop$cat lib/coolprogram.ex
defmodule CoolProgram do
def temperature_of(cities) do
coordinator_pid = spawn(CoolProgram.Coordinator, :loop, [[], Enum.count(cities)])
cities |> Enum.each(fn city ->
worker_pid = spawn(CoolProgram.Worker, :loop, [])
send(worker_pid, {coordinator_pid, city})
end)
end
end
angelcool@fedora-laptop$cat lib/coordinator.ex
defmodule CoolProgram.Coordinator do

def loop(results \\ [], results_expected) do
receive do
{:ok, result} ->
new_results = [result|results]
if results_expected == Enum.count(new_results) do
send(self(), :exit)
end
loop(new_results, results_expected)
:exit ->
IO.puts(results |> Enum.sort |> Enum.join(", "))
_->
loop(results, results_expected)
end
end

end
angelcool@fedora-laptop$cat lib/worker.ex
defmodule CoolProgram.Worker do

def temperature_of(location) do
result = url_for(location)
|> HTTPoison.get
|> parse_response
case result do
{:ok, temp} ->
"#{location}: #{temp}° C"
:error ->
"#{location} not found"
end
end

defp url_for(location) do
location = URI.encode(location)
"http://api.openweathermap.org/data/2.5/weather?q=#{location}&appid=#{apikey()}"
end

defp parse_response({:ok, %HTTPoison.Response{body: body, status_code: 200}}) do
body
|> JSON.decode!
|> compute_temperature()
end

defp parse_response(_) do
:error
end

defp compute_temperature(json) do
try do
temp = (json["main"]["temp"]-273.15)
|> Float.round(1)
{:ok, temp}
rescue
_-> :error
end
end

defp apikey do
"XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
end

def loop do
receive do
{sender_pid, location}->
send(sender_pid, {:ok, temperature_of(location)})
_->
IO.puts "don't know how to process this message"
end
loop()
end
end
angelcool@fedora-laptop$
angelcool@fedora-laptop$iex --version
IEx 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$iex -S mix
Compiling 1 file (.ex)
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.7) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> cities=["San Diego", "Merida", "Singapore", "Los Angeles", "Mexico City", "Miami", "Temecula", "Buenos Aires", "Ojai" ]
["San Diego", "Merida", "Singapore", "Los Angeles", "Mexico City", "Miami",
"Temecula", "Buenos Aires", "Ojai"]
iex(2)> CoolProgram.temperature_of(cities)
:ok
Buenos Aires: 17.0° C, Los Angeles: 14.7° C, Merida: 25.0° C, Mexico City: 22.8° C, Miami: 22.0° C, Ojai: 14.2° C, San Diego: 15.2° C, Singapore: 30.8° C, Temecula: 13.1° C
iex(3)>


[ view entry ] ( 45 views )   |  print article
Elixir: Miscellaneous Notes 
# Filtering files in a directory by filename
angelcool@fedora-laptop$date
Fri Apr 12 12:02:42 PM PDT 2024
angelcool@fedora-laptop$iex
...
iex(90)> "/home/angelcool/Downloads" \
...(90)> |> Path.join("**/*.rpm") \
...(90)> |> Path.wildcard \
...(90)> |> Enum.filter(fn fname -> String.contains?(Path.basename(fname),"dbeaver") end)
["/home/angelcool/Downloads/dbeaver-ce-24.0.2-stable.x86_64.rpm"]


# Making an HTTP GET request
iex(18)> :inets.start()
:ok
iex(19)> :ssl.start()
:ok
iex(20)> :httpc.request(:get, {'https://www.angelcool.net', []}, [ssl: :httpc.ssl_verify_host_options(true)], [])
...


[ view entry ] ( 38 views )   |  print article
Elixir: Clustering Elixir Nodes - Updating Shared State. 

angelcool@fedora-laptop$ # Let's get the date and versions used
angelcool@fedora-laptop$date
Sat Apr 6 11:51:08 AM PDT 2024
angelcool@fedora-laptop$iex --version
IEx 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$mix --version
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Mix 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$mix phx.new --version
Phoenix installer v1.7.11
angelcool@fedora-laptop$
angelcool@fedora-laptop$
angelcool@fedora-laptop$
angelcool@fedora-laptop$ # The gist of this post...
angelcool@fedora-laptop$
angelcool@fedora-laptop$ # Terminal 1
angelcool@fedora-laptop$ iex --name a@127.0.0.1
iex(a@127.0.0.1)1>

angelcool@fedora-laptop$ #Terminal 2
angelcool@fedora-laptop$ iex --name b@127.0.0.1
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.7) - press Ctrl+C to exit (type h() ENTER for help)
iex(b@127.0.0.1)1> Node.connect :"a@127.0.0.1"
true
iex(b@127.0.0.1)2> Node.list
[:"a@127.0.0.1"]
iex(b@127.0.0.1)3>

# Terminal 1
iex(a@127.0.0.1)> Agent.start(
fn -> %{hello: "world"} end,
name: {:global, GlobalAgent}
)
{:ok, #PID<0.116.0>}

# Terminal 2
iex(b@127.0.0.1)4> Agent.get {:global,GlobalAgent}, &(&1)
%{hello: "world"}

# Terminal 2 - Update state
iex(b@127.0.0.1)5> Agent.update {:global, GlobalAgent}, fn _ -> %{hello: "everyone!"} end
:ok
iex(b@127.0.0.1)6>

# Terminal 2 - Get new state
iex(b@127.0.0.1)6> Agent.get {:global,GlobalAgent}, &(&1)
%{hello: "everyone!"}

# Terminal 1 - Get new state
iex(a@127.0.0.1)2> Agent.get {:global,GlobalAgent}, &(&1)
%{hello: "everyone!"}


[ view entry ] ( 60 views )   |  print article
Elixir: Processes Talking Amongst Themselves 
angelcool@fedora-laptop$date
Tue Apr 2 11:31:57 AM PDT 2024
angelcool@fedora-laptop$mix new process-demo --app process_a
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/process_a.ex
* creating test
* creating test/test_helper.exs
* creating test/process_a_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

cd process-demo
mix test

Run "mix help" for more commands.
angelcool@fedora-laptop$
angelcool@fedora-laptop$cd process-demo/
angelcool@fedora-laptop$ls -l
total 8
drwxr-xr-x. 1 angelcool angelcool 24 Apr 2 11:31 lib
-rw-r--r--. 1 angelcool angelcool 575 Apr 2 11:31 mix.exs
-rw-r--r--. 1 angelcool angelcool 476 Apr 2 11:31 README.md
drwxr-xr-x. 1 angelcool angelcool 66 Apr 2 11:31 test
angelcool@fedora-laptop$
angelcool@fedora-laptop$cat lib/process_a.ex
defmodule ProcessA do
def receiverA(count) do
receive do
{from, message} -> send(from, {"Greetings from ProcessA!.", message})
receiverA(count+1)
end
end
end
angelcool@fedora-laptop$cat lib/process_b.ex
defmodule ProcessB do
def initialize do
pid_A = spawn(ProcessA, :receiverA, [1])
recieverB(pid_A)
end

def recieverB(pid_A) do
receive do
{message} ->
send(pid_A, {self(), message})
recieverB(pid_A)
{response, originalmessage} ->
IO.puts("Response: #{response}")
IO.puts("Original Message: #{originalmessage}")
recieverB(pid_A)
end
end
end
angelcool@fedora-laptop$
angelcool@fedora-laptop$iex --version
IEx 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$
angelcool@fedora-laptop$mix phx.new --version
Phoenix installer v1.7.11
angelcool@fedora-laptop$
angelcool@fedora-laptop$iex -S mix
Compiling 2 files (.ex)
Generated process_a app
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.7) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> pid_B = spawn(ProcessB, :initialize, [])
#PID<0.166.0>
iex(2)> send(pid_B, {"Hi! This is a message from process B!"})
Response: Greetings from ProcessA!.
{"Hi! This is a message from process B!"}
Original Message: Hi! This is a message from process B!
iex(3)>


[ view entry ] ( 52 views )   |  print article
Iperf - 1000BASE-LX SMF LC/LC Fiber Link Speed Test 
HOST A - SERVER

angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$ date
Sun Mar 3 02:04:35 PM PST 2024

#IPv4
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$ iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 128 KByte (default)
------------------------------------------------------------
[ 1] local 192.168.1.184 port 5001 connected with 192.168.1.192 port 57642 (icwnd/mss/irtt=14/1448/515)
[ ID] Interval Transfer Bandwidth
[ 1] 0.00-10.01 sec 1.10 GBytes 941 Mbits/sec
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$

# IPv6
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$ iperf -s -V
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 128 KByte (default)
------------------------------------------------------------
[ 1] local 2603:8000:6a00:5748:xxxx:xxxx:xxxx:xxxx port 5001 connected with 2603:8000:6a00:5748:xxxx:xxxx:xxxx:xxxx port 56868 (icwnd/mss/irtt=13/1428/460)
[ ID] Interval Transfer Bandwidth
[ 1] 0.00-10.02 sec 1.08 GBytes 928 Mbits/sec
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$


HOST B - CLIENT

acool@localhost ~]$
# IPv4
[acool@localhost ~]$ iperf -c 192.168.1.184
------------------------------------------------------------
Client connecting to 192.168.1.184, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[ 1] local 192.168.1.192 port 57642 connected with 192.168.1.184 port 5001 (icwnd/mss/irtt=14/1448/731)
[ ID] Interval Transfer Bandwidth
[ 1] 0.00-10.02 sec 1.10 GBytes 940 Mbits/sec

# IPv6
[acool@localhost ~]$ iperf -c 2603:8000:6a00:xxxx:xxxx:xxxx:xxxx
------------------------------------------------------------
Client connecting to 2603:8000:6a00:xxxx:xxxx:xxxx:xxxx, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[ 1] local 2603:8000:6a00:5748:: port 56868 connected with 2603:8000:6a00:5748:xxxx:xxxx:xxxx:xxxx port 5001 (icwnd/mss/irtt=13/1428/783)
[ ID] Interval Transfer Bandwidth
[ 1] 0.00-10.02 sec 1.08 GBytes 928 Mbits/sec
[acool@localhost ~]$


[ view entry ] ( 58 views )   |  print article
SSL/TLS: Wildcard certificate 
Tested and working on 11/15/2023 !

# Create root CA
[acool@localhost tls]$openssl req --x509 --nodes --days 3650 --newkey rsa:2048 --keyout ENT-CA.key --out ENT-CA.crt

# Crate new key and signing request (Tip: remove --aes256 to remove passphrase requirement... I think)
Passphrase: mypassphrase
[acool@localhost tls]$openssl genrsa --out star-dev-localhost.key --aes256 2048
[acool@localhost tls]$openssl req --new --key star-dev-localhost.key --out star-dev-localhost.csr

# Sign request
[acool@localhost tls]$openssl x509 --req --in star-dev-localhost.csr --CA ENT-CA.crt --CAkey ENT-CA.key --CAcreateserial --days 3650 --sha256 --extfile star-dev-localhost.cnf --out star-dev-localhost.crt

# remove passphrase
[acool@localhost tls]$openssl rsa --in star-dev-localhost.key --out star-dev-localhost-nopassphrase.key

[acool@localhost tls]$ cat star-dev-localhost.cnf
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.dev.localhost
[acool@localhost tls]$
[acool@localhost tls]


# finally, import ENT-CA.crt certificate in Chrome
# chrome://settings/certificates


Configure Nginx:
...
listen 443 ssl;
ssl_certificate /etc/ssl/certs/star-dev-localhost.crt;
ssl_certificate_key /etc/ssl/certs/star-dev-localhost-nopassphrase.key;
...


[ view entry ] ( 157 views )   |  print article
C 101: Foreach loop macro 
[acool@localhost ~]$ 
[acool@localhost ~]$ date
Mon Apr 3 11:17:50 AM PDT 2023
[acool@localhost ~]$
[acool@localhost ~]$ cat c-foreach-macro.c
#include <stdio.h>

#define foreach(item, array) \
for(int keep = 1, \
count = 0,\
size = sizeof (array) / sizeof *(array); \
keep && count != size; \
keep = !keep, count++) \
for(item = (array) + count; keep; keep = !keep)

int main()
{
int mynumbers[] = {5,20,35,62,8,74,89};

char mygreeting[] = {"Hello world!"};

float myfloats[] = {1.6,6.9,5.8,43.5,1.1,0.9};

foreach(int *v, mynumbers) {
printf("value: %d\n", *v);
}

foreach(char *v, mygreeting) {
printf("value: %c\n", *v);
}

foreach(float *v, myfloats) {
printf("value: %.2f\n", *v);
}

return 0;
}
[acool@localhost ~]$
[acool@localhost ~]$ gcc c-foreach-macro.c -o c-foreach-macro
[acool@localhost ~]$
[acool@localhost ~]$ ./c-foreach-macro
value: 5
value: 20
value: 35
value: 62
value: 8
value: 74
value: 89
value: H
value: e
value: l
value: l
value: o
value:
value: w
value: o
value: r
value: l
value: d
value: !
value:
value: 1.60
value: 6.90
value: 5.80
value: 43.50
value: 1.10
value: 0.90
[acool@localhost ~]$


Bonus - dumping output from preprocessor.
[acool@localhost ~]$ 
[acool@localhost ~]$ gcc c-foreach-macro.c -E -o c-macro.preprocessed
[acool@localhost ~]$
[acool@localhost ~]$ cat c-macro.preprocessed
...
int main()
{
int mynumbers[] = {5,20,35,62,8,74,89};

char mygreeting[] = {"Hello world!"};

float myfloats[] = {1.6,6.9,5.8,43.5,1.1,0.9};

for(int keep = 1, count = 0, size = sizeof (mynumbers) / sizeof *(mynumbers); keep && count != size; keep = !keep, count++) for(int *v = (mynumbers) + count; keep; keep = !keep) {
printf("value: %d\n", *v);
}

for(int keep = 1, count = 0, size = sizeof (mygreeting) / sizeof *(mygreeting); keep && count != size; keep = !keep, count++) for(char *v = (mygreeting) + count; keep; keep = !keep) {
printf("value: %c\n", *v);
}

for(int keep = 1, count = 0, size = sizeof (myfloats) / sizeof *(myfloats); keep && count != size; keep = !keep, count++) for(float *v = (myfloats) + count; keep; keep = !keep) {
printf("value: %.2f\n", *v);
}

return 0;
}
[acool@localhost ~]$


[ view entry ] ( 196 views )   |  print article
C 101: Creating Child Processes With A Loop 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void child( int seconds );

int children = 15;

int main(void)
{
printf("Parent ID %d, Main ID %d \n", getppid(), getpid());

for(int i=0;i<children;i++)
{
if(fork()==0)
{
child(children-i); // pass seconds to sleep
}
else
{
wait(NULL);
}
}
}

void child(int seconds)
{
printf("Parent ID %d, Child ID %d, Sleeping %d seconds.\n", getppid(), getpid(), seconds);
sleep(seconds);
exit(0);
}

[acool@localhost C-Exercises]$ date
Sun Oct 23 04:14:24 PM PDT 2022
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ gcc parent_children.c
[acool@localhost C-Exercises]$ ./a.out
Parent ID 4298, Main ID 10357
Parent ID 10357, Child ID 10358, Sleeping 15 seconds.
Parent ID 10357, Child ID 10394, Sleeping 14 seconds.
Parent ID 10357, Child ID 10436, Sleeping 13 seconds.
Parent ID 10357, Child ID 10475, Sleeping 12 seconds.
Parent ID 10357, Child ID 10510, Sleeping 11 seconds.
Parent ID 10357, Child ID 10532, Sleeping 10 seconds.
Parent ID 10357, Child ID 10546, Sleeping 9 seconds.
Parent ID 10357, Child ID 10558, Sleeping 8 seconds.
Parent ID 10357, Child ID 10581, Sleeping 7 seconds.
Parent ID 10357, Child ID 10598, Sleeping 6 seconds.
Parent ID 10357, Child ID 10607, Sleeping 5 seconds.
Parent ID 10357, Child ID 10613, Sleeping 4 seconds.
Parent ID 10357, Child ID 10647, Sleeping 3 seconds.
Parent ID 10357, Child ID 10732, Sleeping 2 seconds.
Parent ID 10357, Child ID 10815, Sleeping 1 seconds.
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ ps -A |grep a.out
10357 pts/0 00:00:00 a.out
10394 pts/0 00:00:00 a.out
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ pstree -p 10357
a.out(10357)───a.out(10436)
[acool@localhost C-Exercises]$

Slightly different version, in this version we don't wait() for each child individually.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void child( int seconds );

int children = 15;

int main(void)
{
printf("Parent ID %d, Main ID %d \n", getppid(), getpid());

for(int i=0;i<children;i++)
{
if(fork()==0)
{
child(children-i); // pass seconds to sleep
}
}

while (wait(NULL) > 0); // wait for all children to finish
}

void child(int seconds)
{
printf("Parent ID %d, Child ID %d, Sleeping %d seconds.\n", getppid(), getpid(), seconds);
sleep(seconds);
exit(0);
}

[acool@localhost C-Exercises]$ 
[acool@localhost C-Exercises]$ gcc parent_children.c
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ ./a.out
Parent ID 4298, Main ID 14322
Parent ID 14322, Child ID 14323, Sleeping 15 seconds.
Parent ID 14322, Child ID 14324, Sleeping 14 seconds.
Parent ID 14322, Child ID 14325, Sleeping 13 seconds.
Parent ID 14322, Child ID 14326, Sleeping 12 seconds.
Parent ID 14322, Child ID 14327, Sleeping 11 seconds.
Parent ID 14322, Child ID 14328, Sleeping 10 seconds.
Parent ID 14322, Child ID 14329, Sleeping 9 seconds.
Parent ID 14322, Child ID 14330, Sleeping 8 seconds.
Parent ID 14322, Child ID 14331, Sleeping 7 seconds.
Parent ID 14322, Child ID 14332, Sleeping 6 seconds.
Parent ID 14322, Child ID 14333, Sleeping 5 seconds.
Parent ID 14322, Child ID 14334, Sleeping 4 seconds.
Parent ID 14322, Child ID 14335, Sleeping 3 seconds.
Parent ID 14322, Child ID 14336, Sleeping 2 seconds.
Parent ID 14322, Child ID 14337, Sleeping 1 seconds.
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ pstree -p 14322
a.out(14322)─┬─a.out(14323)
├─a.out(14324)
├─a.out(14325)
├─a.out(14326)
├─a.out(14327)
├─a.out(14328)
├─a.out(14329)
├─a.out(14330)
├─a.out(14331)
├─a.out(14332)
├─a.out(14333)
├─a.out(14334)
└─a.out(14335)
[acool@localhost C-Exercises]$ ps -A |grep a.out
14322 pts/0 00:00:00 a.out
14323 pts/0 00:00:00 a.out
14324 pts/0 00:00:00 a.out
14325 pts/0 00:00:00 a.out
14326 pts/0 00:00:00 a.out
14327 pts/0 00:00:00 a.out
14328 pts/0 00:00:00 a.out
14329 pts/0 00:00:00 a.out
14330 pts/0 00:00:00 a.out
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ pstree -p 14322
a.out(14322)─┬─a.out(14323)
├─a.out(14324)
├─a.out(14325)
├─a.out(14326)
├─a.out(14327)
└─a.out(14328)
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$


[ view entry ] ( 232 views )   |  print article
C101: Printing Emojis 
#include <stdio.h>
#include <wchar.h>
#include <locale.h>

// multibyte array, each character is 4 bytes long
wchar_t mystring[] = L"Angel Cool á 🤪 😁 ა";

// [acool@localhost other]$ gcc -Wall -ggdb emoji-multibyte-array.c -o emoji-multibyte-array
int main()
{
setlocale(LC_ALL,"");

// print total number of characters in string
wprintf(L"wcslen of wchar_t mystring[]: %ld\n", wcslen(mystring));

// output string
wprintf(L"%ls\n",mystring);

// print one character
wprintf(L"Emoji : %lc\n", mystring[13]);

// print all
for (int j = 0; j < wcslen(mystring); ++j)
{
wprintf(L"%lc,", mystring[j]);
}

wprintf(L"\n");

// size in bytes of string, it also includes 4 bytes for the null (\0) characters at the end it seems
wprintf(L"Size in bytes of mystring[]: %d\n", sizeof(mystring));

// print size of wchar_t data type
wprintf(L"wchar_t is %d bytes long!\n", sizeof(wchar_t));

return 0;
}

[acool@localhost other]$ date
Sat Oct 22 12:05:24 PM PDT 2022
[acool@localhost other]$ gcc emoji-multibyte-array.c
[acool@localhost other]$ ./a.out
wcslen of wchar_t mystring[]: 18
Angel Cool á 🤪 😁 ა
Emoji : 🤪
A,n,g,e,l, ,C,o,o,l, ,á, ,🤪, ,😁, ,ა,
Size in bytes of mystring[]: 76
wchar_t is 4 bytes long!
[acool@localhost other]$


[ view entry ] ( 205 views )   |  print article

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Next> Last>>


2024 By Angel Cool