Networking - C Threads in Linux

    After talking about Processes here we will today talk about Threads also. I will first start out with what Threads are getting into the differences with Processes and finish of with the implementation in C Linux. So, without further do let's get started!


Linux Threads:

    Each Process in Linux has at least 1 Thread that is the main thread. When creating a new Thread constant variables, open files and signal handlers  are being used in a common memory address for all threads. In Processes each new Process has a copy from everything as you might remember and so we don't have common memory, but we can do this in another way that we will talk about another time! 

    Threads get also scheduled, but using the Thread Scheduler. In different circumstances and operation systems threads or processes will be preferable. What is the best for each Application depends on the process and thread switching time of the operation system and also on the time that the operation systems takes to create a new process or thread. We will discuss all that later on when we get into different kinds of Servers! 

    The Library-API that we will use in Linux for creating and managing Threads is called pthread.h. This library contains everything that we need. So, let's get into the implementation part now!

Implementation of pthreads in C (Linux):

Creating a Thread:

    The function that does the same as fork() in processes, but for pthreads is called pthread_create(). So, we use pthread_create(&thread, &attributes, function, arguments) to create a new thread that will be stored in thread, has specific attributes that we mostly set to NULL, runs a specific function with the specified arguments/parameters.

This looks like that in Code:

// in main
pthread_t pthread;
int arg = 5;
pthread_create(&pthread, NULL, thread_function, (void*)&arg);
// function thread runs
void *thread_function(void *arg){
    val = *(int*)arg;
    printf("%d", arg);
}


    Don't be scared by the weird syntax in the argument. Me myself always copy paste it from a example programm I have, that looks similar to this one :)


Waiting for thread to finish:

    Another important function that is even more important than in Processes in Threads, is the function that makes the main process or any process/thread that created a child thread wait for the thread to finish. In Processes we called wait or waitpid. In Threads we use pthread_join(thread, result).

So, let's expand our previous Code making the main process wait for the thread to finish:

// in main
pthread_t pthread;
int arg = 5;
pthread_create(&pthread, NULL, thread_function, (void*)&arg);
void* result;
result = pthread_join(pthread, NULL);
if(result != 0){
    printf("thread join failed!\n");
}
// function thread runs
void *thread_function(void *arg){
    val = *(int*)arg;
    printf("%d", arg);
}

    

    I put NULL inside of the return value, just to show you that you don't have to get a return value. But, you could also get a return value.


Exiting a Thread:

     Lastly, there is also pthread_exit(return_val) that is for terminating a thread on a given point of Code. We can get this return value with the pthread_join function to make our thread feedback information to the process that created it.

So, the thread may send back a string like that:

pthread_exit("My name is Jeff!");

And then the process can print this out like that:

void *thread_result;
pthread_join(pthread, &thread_result);
printf("%s\n", (char *)thread_result);


Multiple Threads:

    That way we actually talked about everything. You can now create a thread and pass arguments to it, and also exit a thread with a return value that gets passed to the process that waits for it. The only thing left are multiple Threads, but I guess you can do it easily. 

     Here's how you create and wait for multiple threads without arguments and return values and using the same function:

// include &ltstdioode and pthread librariesh&
#define N 10
int main{
    int i;
    pthread_t = threads[N];
    // create threads
    for(i = 0; i < N; i++){
        pthread_create(&threads[i], NULL, example, NULL);
    }
    printf("successfully created threads\n");
    // wait for threads
    for(i = 0; i < N; i++){
        pthread_join(threads[i], NULL);
    }
    printf("threads finished\n");
}
void *example(){
    sleep(1 + rand()%3); // random sleep
    printf("I am a thread!\n);
}


    Lastly, I wanted to tell you that compiling the Code in the Terminal now needs also another argument. You will have to include the pthread library. This can be done this way:

gcc -o output_name code.c -lpthread


And this is actually it for today! Hope you enjoyed it!

Next time we will get into the Synchronization of Processes and Threads.

Until next time...Bye!

H2
H3
H4
3 columns
2 columns
1 column
9 Comments