Pthread Tutorial – Simplified

Threads – What are they ?

Threads are often described as light-weight processes. They can work like two or more processes sharing the same address space ie they will work independently like processes but can share the same global variables.They are mostly used when two tasks can be done independently without depending much on each other.As an example your IM client might launch one thread for each conversation ( if I am talking to A and B, the two conversations are totally computationally independent from each other ).

Hello Threads !

 
Lets get down to business. A simple thread hello world. I’ll explain only the important parts.

#include<stdio.h>
#include<pthread.h>

void* say_hello(void* data)
{
	char *str;
	str = (char*)data;
	while(1)
	{
		printf("%s\n",str);
		sleep(1);
	}
}

void main()
{
	pthread_t t1,t2;

	pthread_create(&t1,NULL,say_hello,"hello from 1");
	pthread_create(&t2,NULL,say_hello,"hello from 2");
	pthread_join(t1,NULL);
}

 

Explanation

Compile and run the above code with

gcc thread.c -o thread -lpthread

The –lpthread at the end to link the pthread library

#include<pthread.h>

The default threading library in Linux. pthread stands for POSIX threads. Include it to enable thread support for your C program

void* say_hello(void* data)
{
	char *str;
	str = (char*)data;
	while(1)
	{
		printf("%s\n",str);
		sleep(1);
	}
}

Each thread executes a function. In this case the function prototype is predefined. The function needs to have a void* pointer as argument and must return a void* pointer ( void* can be interpreted as a pointer to anything ).
The function converts the data pointer to a string pointer str and runs a while loop to print it,the sleep function pauses the thread for 1 second as specified. Needless to say that the function never returns.

pthread_t t1,t2;

pthread_t is a data type that holds information about threads. Each thread requires one pthread_t variable

pthread_create(&t1,NULL,say_hello,"hello from 1");

The above function creates a thread. Lets look at the prototype

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void*), void *arg);

thread
is a pthread_t variable in our case t1 and t2.
attr
is a variable of type pthread_attr_t, if specified it holds details about the thread, like scheduling policy, stack size etc. Since we have specified NULL the thread runs with default parameters.
start_routine
is the function the thread executes. In our case it is the ever so friendly say_hello function.
arg
is a void pointer which points to any data type. This same pointer is passes to the start_routine function when it is called. In our case the strings hello from 1/hello from 2 are passed to the say_hello function in the data variable.

pthread_join(t1,NULL);

pthread_joinwaits for the thread specifies in the first argument to exit, which in our case doesn’t happen, so the program runs forever, unless you interrupt it with Ctrl-C etc.

The second argument is a pointer to the variable specified by pthread_exit in case the thread calls the function to exit. Since it is NULL, it is ignored.

The idea behind threads

It is easy to visualize how threads on modern CPUs with multiple cores can work. If there are 2 threads and 2 cores, one core gets one thread.But , hey !! Hang on a second . Threads have been existing since before Multi-Core CPUs became common. So can two threads run on just 1 CPU.

The answer is, they don’t. One CPU runs only one thread at a time, but it switches between them so fast, that we don’t notice. But one particular advantage is, while one thread is waiting for an event ( like hard disk to be ready to read a file ),it doesn’t need the CPU. And the other threads( if they want ) can happily claim the CPU.

Also note that one a Single Core CPU two threads which only do computations ( CPU bound threads ) are practically useless. Getting the job done from 2 threads simultaneously will approximately be same as gettting one job done after another.

The following example illustrates one CPU and one I/O bound thread.

#include<stdio.h>
#include<pthread.h>

void* say_hello(void* data)
{
	char *str;
	str = (char*)data;
	while(1)
	{
		printf("%s\n",str);
		usleep(1);
	}
}

void* open_file(void* data)
{
	char *str;
	str = (char*)data;
	printf("Opening File\n");
	FILE* f = fopen(str,"w");
	fclose(f);
	printf("Closing File\n");
}

void main()
{
	pthread_t t1,t2;

	pthread_create(&t1,NULL,open_file,"hello.txt");
	pthread_create(&t2,NULL,say_hello,"The CPU is mine now :D");
	pthread_join(t1,NULL);
}

usleep pauses the calling thread for the specified time in microseconds

Here is the output incase you are too lazy !

Opening File
The CPU is mine now 😀
The CPU is mine now 😀
Closing File

while t1 opens a file ,t2 is pretty happy to claim the CPU.

Finally

Many people don’t consider you as a serious programer unless you know about threads. But threads can be a blessing in disguise if not used properly. Their worst curse is Data Inconsistency. I will highlight it in my next post here

9 thoughts on “Pthread Tutorial – Simplified

    • pthread.h is included in any standard Linux distribution. What OS are you running ? Windows does not support POSIX threads and even if you had the header file, you would get compiler errors due to other missing dependencies.

      Thanks
      Vighnesh

  1. Excuse me, sir.
    I have two quick questions:
    1. when you use pthread_create function, It will invoke start_routine function automatically and execute start_routine function ? (seems like procedure parameter)

    2. I do not understand how the pthread and I/O work together, can you explain it more specific ?
    It seems that you create a file F in the current directory, and try to open it, but I think it a little bit confused.
    e.g.
    pthread_create(&t1,NULL,open_file,”hello.txt”);
    pthread_create(&t2,NULL,say_hello,”The CPU is mine now :D”);
    ————————————————————————————-
    void* say_hello(void* data);
    void* open_file(void* data);
    —————————————————————-
    output:
    Opening File

    The CPU is mine now 😀
    The CPU is mine now 😀
    // these two lines are not clear-cut for me

    Closing File

    Thank you for your consideration!

  2. Pingback: Simple multi threading in C | An Integrated World
  3. Pingback: Part – 2: Program, Process, Threads & Why Grand Central Dispatch | iosdailydose
  4. Pingback: Part 2: Program, Process, Threads & Why Grand Central Dispatch – A dose on IOS stuff

Leave a reply to jeff cheng Cancel reply