Archive

Another way of facing concurrency in the wonderful world of doing several task at the same time is using child processes with fork(). The main difference between fork and threads is that forked process are full process, they have their own memory for code, for data and stack, while threads share code and data, and have their own stack.

But, what about sharing variables in forked processes? If we try to make it as simpler as in thread examples, it’s not going to work, because as they are different processes, they are using different memory zones for their data. For example:

In our ideal world, the MAIN process can see the values written by CHILD and vice versa, but the value the MAIN process can access is completely different than the value the CHILD can access, even using malloc before calling fork(). fork() copies the values of all variables before fork(), but the physical memory address is different.

To do that we have to work with shared memory, have to use mmap instead of malloc:

If you are creating a program which interacts with a server, this may interest you. First, we’re going to make a simple TCP client, we connect to a server and it will allow us to send whatever we write on our keyboard. We can’t receive anything from the server right now, it’s just a first step to reach our goal:

We’ll analyze the main() function directly, because usage() just display text and panic() makes the program exit on an error.
The first thing we do is to determine the server and port we will connect to, they both will be the first and second arguments to our program. Then we create the socket and build the client address. The port is 0 to let the system pick any port, we don’t mind which port is picked. Then bind() will assign the address to the socket.

Then, create the server address. We will use getbyhostname() before because we may resolve the server address first (if it comes with a hostname, or even if it comes as a IP address we will have to translate this address to a suitable format), so let’s connect() and begin sending messages.

In this case we’re using fgets() to ask the user for information through the standard input (usually keyboard) and then send() it, we must set the size to strlen(mens)+1 to include the string terminator ‘\0′ at the end of the string being sent.

Note: fgets() will send the line feed at the end when we press return. We can use a trim() function or filter it with:

Reception is similar to sending, but this time we don’t know the size of the message, so we provide a maximum size (or the size of our buffer), if the size of the data we are receiving is greater than our buffer, we can continue the message calling again and again recv().
As this message may not have a terminator, to display it properly on screen with printf() we must put the terminator manually at the end of the string.

It’s easy. The biggest problem, comes when we want the application to send and receive information whenever there is data on each side (sending or reception), making our application full duplex. With this code, right now, we just can give turns, make the user send information sometimes, and sometimes the application will receive data.
We will make a more complex example using select(), this function will detect whenever there is data waiting on some descriptors, and we can later choose whether to read the socket or the keyboard. But the most interesting is the timeout, we can give select() a wait timeout, when the function will stop waiting and the program can continue, it won’t block indefinitely waiting for data.

do{/* We must set all this information on each select we do */
FD_ZERO(&readmask);/* empty readmask *//* Then we put all the descriptors we want to wait for in a *//* mask = readmask */
FD_SET(socketfd,&readmask);
FD_SET(STDIN_FILENO,&readmask);/* STDIN_FILENO = 0 (standard input) *//* Timeout, we will stop waiting for information */
timeout.tv_sec=0;
timeout.tv_usec=100000;

/* The first parameter is the biggest descriptor+1. The first one
was 0, so every other descriptor will be bigger.*//* readfds = &readmask *//* writefds = we are not waiting for writefds *//* exceptfds = we are not waiting for exception fds */if(select(socketfd+1,&readmask, NULL, NULL,&timeout)==-1)
panic("Error on SELECT");

It’s common, when using more or less complex stored procedures, to make mistakes that make us waste much time, and sometimes we would like to see the value of a variable or the result of a query because it could tell us what’s going wrong.

This is a little help, an easy piece of code we can insert into our database and will let is write in a table what’s happening.

If you have ever program in C, I’m sure you had met printf(), it is, probably, the first thing you used in this language (at least for a Hello World). Well, this function accepts as many arguments as keywords you enter in its first argument, so here we have a variable number of arguments.

Some people think that only printf() and scanf() functions worth it, but there are so many cases where it is needed, for example when creating a function with optional arguments (these functions are common in C++, but C doesn’t allow it so easily), when concatenating some strings, filling data variables, internationalizing, and more.

All we must do is to include stdarg.h wichi provides us the tools to make it happen.

Let’s see this code:

12345678910111213141516171819202122232425262728

#include <stdlib.h>#include <stdio.h>#include <stdarg.h>

void putargs(int nargs, ...){
va_list ap;int i;int num;

va_start(ap, nargs);// nargs, because is the last known argumentfor(i =0; i<nargs; i++){
num=va_arg(ap,int);// All arguments are intprintf("Argument %d = %d\n", i, num);}va_end(ap);printf("\n");}

We can see here, function putargs() prints out values of possible arguments we’ve passed the function, being the first of them the number of arguments we have, because we have no way to count the number of arguments passed (like printf, we will use as many arguments as %[x] we have in the format string). So we will have to use different techniques to know the total number of arguments, like:

Ask the user, like we’ve done here, with an argument telling the function how many arguments to read.

Search for a value inside all arguments, we can read arguments until the value I found is 5 (for example). It is used so often when passing pointers to the function, I will read arguments until I get a NUL value.

Like printf() use a number of keywords, this will be the number of arguments

We just have to copy this sample code and make some test, have in mind when we start looking for arguments, we must call va_start() with a va_list variable and the last known argument we gave the function, then each time we call va_arg, we will get a different argument from the “unknown argument list”, that is the list of arguments starting by the three dots.

In the next example we will have a variable argument function used to fill a struct with people data. We will have the function new_person where we must say the name, but it will add data to the struct as you are adding arguments when you call the function, it’s fun and easy: