mario::konrad
programming / C++ / sailing / nerd stuff
Multithreading: Tutorial 01
© 2002 / Mario Konrad

What is a Thread?

State of the art operating systems can run several processes in parallel. Besides this is a great thing, there are some disadvantages: slow context switch, overhead in communication between the processes. To take care of those problems, there are Threads.

Threads run within the context of a process and have the following characteristics:

In fact, there is a disadvantage resulting from the points above: using processes the operating system takes care of the address spaces, different from threads. Using threads means that the programmer has to take care of starting, stopping even the access to shared memory space. This makes a multithreaded program hard to debug, but: it is fun!

There are two types of threads:

Let's have a look at a very first and simple program.

The Program

First I'd like to have a look at a very simple program. It's so obvious what it does, I don't think it needs any explenation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

void * work(void * ptr)
{
    int i;
    for (i = 0; i < 10; i++)
    {
        printf("%d", (int)ptr);
        usleep(1000);
    }
    return 0;
}

int main(int argc, char ** argv)
{
    work((void *)0);
    work((void *)1);
    return 0;
}

The program start, it calls the function work twice in series and terminates. The function work prints the specified number 10 times and waits for 1 second after every time. Just plain and simple.

Since this is a tutorial about multithreading, let's change the program in order to let the function work run at the same time instead of in series. To reach this goal we have to do a few things:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <pthread.h>

void * work(void * ptr)
{
    int i;
    for (i = 0; i < 10; i++)
    {
        printf("%d", (int)ptr);
        usleep(1000);
    }
    pthread_exit(0);
}

int main(int argc, char ** argv)
{
    pthread_t t0, t1;

    pthread_create(&t0, 0, work, (void *)0);
    pthread_create(&t1, 0, work, (void *)1);

    pthread_join(t0, 0);
    pthread_join(t1, 0);
    return 0;
}

Walkthrough

The first thing we've changed is to include another header on line 2. We need this header in order to get able to use the pthread library.

2
#include `<pthread.h>`

The function work has only one change: the exit of the function (line 12). This is needed to terminate the thread properly.

12
    pthread_exit(0);

Most of the changes appear in the function main. To start the threads we have to define an ID for each:

17
    pthread_t t0, t1;

The second step is to create the threads. Please note: if you create a thread, it will run immediately!

19
20
    pthread_create(&t0, 0, work, (void *)0);
    pthread_create(&t1, 0, work, (void *)1);

Have a look at the man pages for an explenation of all parameters. The two most important are the first (the ID) and the third (the function to be called).

As mentioned in the introduction What is s Thread?, the programmer (as we are) has to take care of the entire handling, including the proper termination. So we have two choices:

  1. wait for the created threads to terminate
  2. detach the threads

We choose no. 1, for now. Ok, let's wait for the threads:

22
23
    pthread_join(t0, 0);
    pthread_join(t1, 0);

There we are! Our first multithreaded program. Frankly, it does nothing outstanding, but it works and gives you a good access to the world of multithreading.

As mentioned before, I assume you to know how to compile and run C programs. So no explanations here, sorry.

Download Source Code

All source code files provided by this page is free to copy, modify, redistribute and use for any purpose. Use it on your own risk. The tutorial is copyrighted by Mario Konrad.