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
can you plz send pthread.h library file. my email id is hiren.tejani@energycloud.co.in
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
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!
I do not understand your first point.
Regarding the second point. The thread opening the file is blocked and the other thread gets to run. That was the idea behind that piece of code.
good read, i have shared it in my blog.
Yoooo! Thanks for the help bro! Need to pay you a coffee someday☕