Pthread_join functionality in Linux C - c

Program:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
void* pfun1(void *vargp);
void* pfun2(void *vargp);
void main(){
int treturn,jreturn;
pthread_t tid1,tid2;
printf("Before thread call\n");
treturn = pthread_create(&tid1,NULL,pfun1,NULL);
treturn = pthread_create(&tid2,NULL,pfun2,NULL);
jreturn = pthread_join(tid1,NULL);
//jreturn = pthread_join(tid2,NULL);
printf("After thread call\n");
}
void* pfun1(void *vargp){
int i;
for(i=0;i<5;i++){
printf("Thread1: %d\n",i);
sleep(1);
}
return (void*)0;
}
void* pfun2(void *vargp){
int i;
for(i=5;i<10;i++){
printf("Thread2: %d\n",i);
sleep(1);
}
return (void*)0;
}
In the above program, I joined only the first thread to the main program using pthread_join(). And the second thread is only created and not attached to main. But output function contains the output of the second thread too. How come it is possible to get the output of 2nd thread even though it is not attached to main?
Output:
Before thread call
Thread2: 5
Thread1: 0
Thread2: 6
Thread1: 1
Thread2: 7
Thread1: 2
Thread2: 8
Thread1: 3
Thread2: 9
Thread1: 4
After thread call

Joining is about synchronization (after a join, the joined thread is definitely finished) and obtaining the return value of the thread (the (void*)0s you're returning in each case).
It has nothing to do with IO redirection. Threads share the same stdout/stdin (as well as other filedescriptors and stdio buffers) and writes to (/reads from) those are immediate. They aren't postponed until the thread is joined.

As i can understand from this link pthread_join just wait for tid1 retrun inside main function, its not prevent tid2 from output. So i think, if you want run tid2 after tid1 just switch the lines:
treturn = pthread_create(&tid1,NULL,pfun1,NULL);
jreturn = pthread_join(tid1,NULL);
treturn = pthread_create(&tid2,NULL,pfun2,NULL);
Im not proffesional at this point, so you can make research for better solution if you want.

Related

Concurrent Multithreading

I'm trying to understand how multithreading works. I've written the following code
`
void handler(void *arg)
{
printf("Printf from cleanup handler: %s\n", (char*)arg);
}
void print(const char *msg)
{
printf("%7s: Pid=%d Tid:%lu\n", msg, getpid(), pthread_self());
}
void* thread_function1(void *args)
{
printf("Received: %d\n", (int)args);
print("Thread");
pthread_cleanup_push(handler, "hello");
pthread_cleanup_pop(1);
printf("Thread Done\n");
return (void *) 0;
}
int main(void)
{
pthread_t tid1, tid2;
void *tret;
if(pthread_create(&tid1, NULL, thread_function1, (void *)1))
exit(1);
if(pthread_create(&tid2, NULL, thread_function1, (void *)2))
exit(1);
// pthread_join(tid2, &tret);
// pthread_join(tid1, &tret);
}
The problem with this code is that the main completes its execution before thread_function1 could complete its execution. If both the comments are removed then thread 2 is executed only after thread 1 has completeted its execution.
What I want to do is have thread 1 and thread 2 execute simultaneously and main should wait for completion of both the threads.
The problem with this code is that the main completes its execution before thread_function1 could complete its execution.
That's because when the main thread exits, the process dies including all threads. You can instead call pthread_exit(0) from the main thread so that the rest of the threads continue execution and the main thread exits.
If both the comments are removed then thread 2 is executed only after thread 1 has completeted its execution.
That's not true. i.e. tid1 and tid2 are executed simultaneously after they are created ("simultaneous execution" depends on your hardware, scheduling policy etc -- but as far as you program is concerned, they can be considered as being executed simultaneously). pthread_join() doesn't control the order of threads' execution. It only affects the order in which the main thread waits for the completion of the threads i.e. main thread waits for tid2 to complete first and then waits for tid1 (if you ncomment those two lines).

pthread_create() Output [duplicate]

this is my first pthread program, and I have no idea why the printf statement get printed twice in child thread:
int x = 1;
void *func(void *p)
{
x = x + 1;
printf("tid %ld: x is %d\n", pthread_self(), x);
return NULL;
}
int main(void)
{
pthread_t tid;
pthread_create(&tid, NULL, func, NULL);
printf("main thread: %ld\n", pthread_self());
func(NULL);
}
Observed output on my platform (Linux 3.2.0-32-generic #51-Ubuntu SMP x86_64 GNU/Linux):
1.
main thread: 140144423188224
tid 140144423188224: x is 2
2.
main thread: 140144423188224
tid 140144423188224: x is 3
3.
main thread: 139716926285568
tid 139716926285568: x is 2
tid 139716918028032: x is 3
tid 139716918028032: x is 3
4.
main thread: 139923881056000
tid 139923881056000: x is 3
tid 139923872798464tid 139923872798464: x is 2
for 3, two output lines from the child thread
for 4, the same as 3, and even the outputs are interleaved.
Threading generally occurs by time-division multiplexing. It is generally in-efficient for the processor to switch evenly between two threads, as this requires more effort and higher context switching. Typically what you'll find is a thread will execute several times before switching (as is the case with examples 3 and 4. The child thread executes more than once before it is finally terminated (because the main thread exited).
Example 2: I don't know why x is increased by the child thread while there is no output.
Consider this. Main thread executes. it calls the pthread and a new thread is created.The new child thread increments x. Before the child thread is able to complete the printf statement the main thread kicks in. All of a sudden it also increments x. The main thread is however also able to run the printf statement. Suddenly x is now equal to 3.
The main thread now terminates (also causing the child 3 to exit).
This is likely what happened in your case for example 2.
Examples 3 clearly shows that the variable x has been corrupted due to inefficient locking and stack data corruption!!
For more info on what a thread is.
Link 1 - Additional info about threading
Link 2 - Additional info about threading
Also what you'll find is that because you are using the global variable of x, access to this variable is shared amongst the threads. This is bad.. VERY VERY bad as threads accessing the same variable create race conditions and data corruption due to multiple read writes occurring on the same register for the variable x.
It is for this reason that mutexes are used which essentially create a lock whilst variables are being updated to prevent multiple threads attempting to modify the same variable at the same time.
Mutex locks will ensure that x is updated sequentially and not sporadically as in your case.
See this link for more about Pthreads in General and Mutex locking examples.
Pthreads and Mutex variables
Cheers,
Peter
Hmm. your example uses the same "resources" from different threads. One resource is the variable x, the other one is the stdout-file. So you should use mutexes as shown down here. Also a pthread_join at the end waits for the other thread to finish its job. (Usually a good idea would also be to check the return-codes of all these pthread... calls)
#include <pthread.h>
#include <stdio.h>
int x = 1;
pthread_mutex_t mutex;
void *func(void *p)
{
pthread_mutex_lock (&mutex);
x = x + 1;
printf("tid %ld: x is %d\n", pthread_self(), x);
pthread_mutex_unlock (&mutex);
return NULL;
}
int main(void)
{
pthread_mutex_init(&mutex, 0);
pthread_t tid;
pthread_create(&tid, NULL, func, NULL);
pthread_mutex_lock (&mutex);
printf("main thread: %ld\n", pthread_self());
pthread_mutex_unlock (&mutex);
func(NULL);
pthread_join (tid, 0);
}
It looks like the real answer is Michael Burr's comment which references this glibc bug: https://sourceware.org/bugzilla/show_bug.cgi?id=14697
In summary, glibc does not handle the stdio buffers correctly during program exit.

How to kill remaining threads when we come out of any single one? [duplicate]

This question already has answers here:
How can I kill a pthread that is in an infinite loop, from outside that loop?
(2 answers)
Closed 8 years ago.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])//main
{
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
pthread_mutex_lock(&lock);
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);//creating thread
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
how to kill remaining all threads when one is release
It is bad design to kill another thread. Standard design is to use a variable to indicate to the thread that it should finish. Each thread should check the variable at suitable points in the code and exit accordingly.
The reason is that only the thread knows when it is a good time to exit and it then can clean up after it self.
If you aren't bothered about bad design of your code I suggest you try pthread_cancel(thread[t]) to cancel the required thread. (refer http://man7.org/linux/man-pages/man3/pthread_cancel.3.html). I think this is a safe way to do it. Ensure you set the cancel state of your thread.
There's another way in which signals can be raised using pthread_kill(thread[t],SIGKILL) (refer: http://man7.org/linux/man-pages/man3/pthread_kill.3.html). This signal SIGKILL will kill your entire process. You can also raise some other signal instead of SIGKILL in case you want to kill selective thread (refer- https://en.wikipedia.org/wiki/Unix_signal#POSIX_signals) in this case you have to use a signal-handler in the thread (refer-[sigaction][1] or [signal][2]) to handle the signal you are trying to raise and handle it appropriately. But note this method is rather complicated as you will have to block signals in threads you don't want to kill.
Implement a two lock solution.
Psuedo code:
void *PrintHello() {
wait_for(lock1);
if( test_and_set(lock2) == true) {
release_others();
/* Do my stuffstuff... */
} else {
/* I'm not first. Exit. */
pthread_exit(null);
}
}

How does this pthread_cond_wait() example work?

I got the below code from this website:
https://computing.llnl.gov/tutorials/pthreads/#Abstract
This simple example code demonstrates the use of several Pthread
condition variable routines. The main routine creates three threads.
Two of the threads perform work and update a "count" variable. The
third thread waits until the count variable reaches a specified value.
My question is- how does the below code ensure that one of the two worker threads doesn't lock on the mutex before the watcher thread locks on it? If this was to happen, the watcher thread would be locked out and pthread_cond_wait(&count_threshold_cv, &count_mutex) would never get called?
I am under the assumption pthread_create() actually begins the thread too. Is the only reason this works because the pthread_create() for the watcher thread begins before the pthread_create() for the two worker threads?! Surely this is not cast-iron and the scheduling could cause a worker thread to begin before the watcher thread? Even the compiler could potentially re-order these lines of code?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 3
#define TCOUNT 10
#define COUNT_LIMIT 12
int count = 0;
int thread_ids[3] = {0,1,2};
pthread_mutex_t count_mutex;
pthread_cond_t count_threshold_cv;
void *inc_count(void *t)
{
int i;
long my_id = (long)t;
for (i=0; i<TCOUNT; i++) {
pthread_mutex_lock(&count_mutex);
count++;
/*
Check the value of count and signal waiting thread when condition is
reached. Note that this occurs while mutex is locked.
*/
if (count == COUNT_LIMIT) {
pthread_cond_signal(&count_threshold_cv);
printf("inc_count(): thread %ld, count = %d Threshold reached.\n",
my_id, count);
}
printf("inc_count(): thread %ld, count = %d, unlocking mutex\n",
my_id, count);
pthread_mutex_unlock(&count_mutex);
/* Do some "work" so threads can alternate on mutex lock */
sleep(1);
}
pthread_exit(NULL);
}
void *watch_count(void *t)
{
long my_id = (long)t;
printf("Starting watch_count(): thread %ld\n", my_id);
/*
Lock mutex and wait for signal. Note that the pthread_cond_wait
routine will automatically and atomically unlock mutex while it waits.
Also, note that if COUNT_LIMIT is reached before this routine is run by
the waiting thread, the loop will be skipped to prevent pthread_cond_wait
from never returning.
*/
pthread_mutex_lock(&count_mutex);
while (count<COUNT_LIMIT) {
pthread_cond_wait(&count_threshold_cv, &count_mutex);
printf("watch_count(): thread %ld Condition signal received.\n", my_id);
count += 125;
printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
}
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
int i, rc;
long t1=1, t2=2, t3=3;
pthread_t threads[3];
pthread_attr_t attr;
/* Initialize mutex and condition variable objects */
pthread_mutex_init(&count_mutex, NULL);
pthread_cond_init (&count_threshold_cv, NULL);
/* For portability, explicitly create threads in a joinable state */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&threads[0], &attr, watch_count, (void *)t1);
pthread_create(&threads[1], &attr, inc_count, (void *)t2);
pthread_create(&threads[2], &attr, inc_count, (void *)t3);
/* Wait for all threads to complete */
for (i=0; i<NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
printf ("Main(): Waited on %d threads. Done.\n", NUM_THREADS);
/* Clean up and exit */
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
pthread_exit(NULL);
}
My question is- how does the below code ensure that one of the two worker threads doesn't lock on the >mutex before the watcher thread locks on it?
The code doesn't need to ensure that. It doesn't depend on the watcher thread calling pthread_cond_wait().
The watcher thread checks count<COUNT_LIMIT, this is the actual condition the thread care about - or rather the inverse, when count >= COUNT_LIMIT - the watcher thread knows that the other threads are done.
The pthread condition variable used in pthread_cond_wait() is just needed in case the threads are not done, so the watcher thread can be put to sleep and woken up to check the condition it cares about.
That said, the example looks a tad silly, it's not quite clear what watcher thread wants to achieve by doing count += 125;
the comment in your code explains that you do not have to worry about that:
Also, note that if COUNT_LIMIT is reached before this routine is run by
the waiting thread, the loop will be skipped to prevent pthread_cond_wait
from never returning.
in fact, if you notice, the while loop is run only if COUNT_LIMIT is not already reached by count. If that is the case, the pthread_cond_signal is not called at all.

Wrong thread IDs in a multithreaded C program?

I am new to multithreading in C and I had this question. I wrote the following code:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
pthread_attr_t attr;
void* test(void *a)
{
int i=*((int *)a);
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
sleep(1);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
int main()
{
int i=0;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
pthread_t thread[5];
for (i=0;i<5;i++)
pthread_create(&thread[i],&attr,test,&i);
for (i=0;i<5;i++)
pthread_join(thread[i],NULL);
return 0;
}
Why do I get values like:
The thread 0 has started.
The thread 0 has started.
The thread 5 has started.
The thread 5 has started.
The thread 0 has started.
The thread 0 has finished.
The thread 0 has finished.
The thread 5 has finished.
The thread 5 has finished.
The thread 0 has finished.
or
The thread 1 has started.
The thread 2 has started.
The thread 5 has started.
The thread 4 has started.
The thread 0 has started.
The thread 1 has finished.
The thread 2 has finished.
The thread 5 has finished.
The thread 4 has finished.
The thread 0 has finished.
or even:
The thread 0 has started.
The thread 0 has started.
The thread 0 has started.
The thread 0 has started.
The thread 0 has started.
The thread 0 has finished.
The thread 0 has finished.
The thread 0 has finished.
The thread 0 has finished.
The thread 0 has finished.
etc, when I expected to get:
The thread 0 has started.
The thread 1 has started.
The thread 2 has started.
The thread 3 has started.
The thread 4 has started.
The thread 0 has finished.
The thread 1 has finished.
The thread 2 has finished.
The thread 3 has finished.
The thread 4 has finished.
Only when I put usleep(10) after thread_create do I get some "normal" values.
I compiled and run this code in Code::Blocks on Unix.
You're passing the address of a variable the for is changing (i) so you're at the mercy of the scheduler. You should just pass a copy. As a cheap, not completely-kosher way:
pthread_create(&thread[i],&attr,test, (void*)i);
/* ... */
int i = (int)a;
Notice that you are passing in the address of i as a parameter to your threads:
pthread_create(&thread[i],&attr,test,&i);
This means that all of your threads will be reading the same variable i to determine which thread they are. That is, all five threads will look at the same variable to determine their thread number. Consequently, as the value of i increments in your for loop, all the threads will perceive their thread number changing to use the new value of i. This is why you're sometimes seeing 5 come up as the thread number, and also explains the fact that you're often skipping numbers or seeing far too many duplicates.
To fix this, you will need to give each thread their own copy of i. For example, you could do something like this:
int* myI = malloc(sizeof(int));
*myI = i;
pthread_create(&thread[i], &attr, test, myI);
And then have the threads free the pointer before terminating:
void* test(void *a)
{
int i=*((int *)a);
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
sleep(1);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
free(a);
}
Alternatively, you could cast i to a void* and pass that in:
pthread_create(&thread[i],&attr,test, (void*)i);
If you do this, you would then have the threads cast their arguments directly back to int, not to int*:
void* test(void *a)
{
int i = (int)a;
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
sleep(1);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
Hope this helps!

Resources