Basics of multithreading in C
Tags: programming, c, threading, multithreading
Published: 2019-01-09 17:20:11

---
title: Basics of multithreading in C
published: true
cover_image: https://thepracticaldev.s3.amazonaws.com/i/d8xzk4f2ckytkexkv5cf.jpg
description: Multithreading is easier than you think
tags: programming, c, threading, multithreading
---

C is a language that runs on one thread by default, which means that the code will only run one instruction at a time. In some cases you'll need to do multiple instructions at a time, a graphical interface for instance, will not stop when it performs an action related to a button's click. That's what we call multithreading, not to be confused with asynchronous operations that can be performed in only one thread that does multiple tasks.


# What is a thread?
A thread is a task that runs linked to a process. A process we can have multiple threads and threads can run other threads and so on.

By default a process runs on a single thread. Each thread is new tasks that can be run indefinitely and in parallel to the other threads.


# Creating a thread
Like said in the title, this post will talk about multithreading in C, so we will do C!

On POSIX operating systems, there is a library named `pthread.h`, which does exactly what it says, create threads! To use it under compilers, you'll need to link it with `-lpthread` argument (ex: `gcc -lpthread main.c`).

```c
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

void
wait(void)
{
    sleep(2);

    printf("Done.\n");
}

int
main(void)
{
    pthread_t thread;
    int err;

    err = pthread_create(&thread, NULL, wait, NULL);

    if (err)
    {
        printf("An error occured: %d", err);
        return 1;
    }

    printf("Waiting for the thread to end...\n");

    pthread_join(thread, NULL);

    printf("Thread ended.\n");    

    return 0;
}
```

The output will be:
```
Waiting for the thread to end...
Done. (~2 seconds after)
Thread ended.
```

The main thread continued and printed a message while the created thread was operating and it's only one line to call a function in a new thread, pretty easy for C uh? Maybe you're a little lost, I will explain the code.

First of all, we include the `pthread.h` library, like said above, it contains all the functions needed to perform multithreading tasks. Then we include `unistd.h` which is containing the `sleep()` function. And then the `stdio.h` for `printf()`.

`pthread_create` function is called to create the thread. It requires a `pthread_t`, which is the thread descriptor, a pointer to a `void` function and some other parameters that I will not describe here, the function's arguments for instance.

`pthread_join` is used to link the current thread process to another thread. It literally makes the program stops in order to wait for the end of the selected thread.

---


# Mutex
Doing multiple operations on one target at the same time is very dangerous, the best example I can give is for databases. If three threads want to write a single file at the same time, it would be a problem because an hard drive can't go as fast as a CPU does. In this case we should lock the other threads in order to not overload the hard drive with tasks that can corrupt the file. Mutex can be used to lock the other threads.

In practice, we use mutex to tell if the task is locked or unlocked.

```c
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

pthread_mutex_t lock;
int j;

void
do_process()
{
    pthread_mutex_lock(&lock);
    int i = 0;

    j++;

    while(i < 5)
    {
        printf("%d", j);
        sleep(1);

        i++;
    }

    printf("...Done\n");
    
    pthread_mutex_unlock(&lock);
}

int
main(void)
{
    int err;
    pthread_t t1, t2;

    if (pthread_mutex_init(&lock, NULL) != 0)
    {
        printf("Mutex initialization failed.\n");
        return 1;
    }

    j = 0;

    pthread_create(&t1, NULL, do_process, NULL);
    pthread_create(&t2, NULL, do_process, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    return 0;
}
```

The output will be:
```
111111...Done
222222...Done
```

So, as you can see, the thread `t2` was done totally after `t1`, so the mutex worked! It's not the result of the `pthread_join` calls as they only change something for the current thread (here the main thread), you can try to join t2 before t1, it will perform the same thing.


# Semaphores
Pretty much the same thing as the mutex, the semaphores are used to be controlled by any thread. The notion of ownership is not present in the case of a semaphore, so they can be locked and unlocked by any part of the program.

---

That was pretty easy don't you think? C functions are very powerful to perform such actions, a great power carries a great responsibility.

![SuperMan](https://media.giphy.com/media/DQ100zzcakfBe/giphy.gif)