This question already has an answer here:
Unexpected output in a multithreaded program
(1 answer)
Closed 4 years ago.
I want to print the passed to create_thread argument. I create an array with 10 int's to simulate the number of each thread -
void* thr_func(void *arg){
printf("\nTHREAD ID %d", *(int*)arg);
return 0;
}
int main(){
int arr[10]={0,1,2,3,4,5,6,7,8,9};
pthread_t thread_id;
for(int i=0;i<10;i++){
pthread_create(&thread_id, NULL, &thr_func,&arr[i]);
}
return 0;
}
Here is the output from two runs
1:
THREAD ID 1
THREAD ID 5
THREAD ID 6
THREAD ID 2
THREAD ID 3
THREAD ID 4
TTHREAD ID 0
THREAD ID 3
2:
THREAD ID 1
THREAD ID 2
THREAD ID 5
THREAD ID 6
THREAD ID 3
THREAD ID 7
THREAD ID 4
THREAD ID 8
THREAD ID 8
I know I can't rely on consecutive numbers, but why does it print some of them twice ?
As #Some programmer dude mentioned, you should always wait for the termination of your single child threads in your main function (except you detach your threads). The reason why some of your arrayelements are printed twice or more often is because before your buffer is cleared the thread may gets killed. (In your case the thread 8). To avoid that the processes are shut-down before they have finished their work you have to waitfor your threads, or in other words you have to join your threads.
That is done by adding the function: pthread_join(pthread_t thread, void **retvalue);
The pthread_join() function waits for the thread specified by thread to terminate.
Just put it in a separate loopafter your pthread_create() function and the parent thread (main) will wait for his childs.
Edit:
To wait for each thread you could change your pthread_tvariable to an array of threads: pthread_t thread[10] so you could wait for each thread in relation to the index.
int arr[10]={0,1,2,3,4,5,6,7,8,9};
pthread_t thread[10];
for(int i=0;i<10;i++){
pthread_create(&thread[i], NULL, &thr_func,&arr[i]);
}
for(int i=0;i<10;i++){
pthread_join(thread[i],NULL);
}
Related
I'm very new to thread coding, so I was doing an exercise I found out there on the web, which asks for something like this:
Write a program hellomany.c that will create a number N of threads specified in the command line, each of which prints out a hello message and its own thread ID. To see how the execution of the threads interleaves, make the main thread sleep for 1 second for every 4 or 5 threads it creates. The output of your code should be similar to:
I am thread 1. Created new thread (4) in iteration 0...
Hello from thread 4 - I was created in iteration 0
I am thread 1. Created new thread (6) in iteration 1...
I am thread 1. Created new thread (7) in iteration 2...
I am thread 1. Created new thread (8) in iteration 3...
I am thread 1. Created new thread (9) in iteration 4...
I am thread 1. Created new thread (10) in iteration 5...
Hello from thread 6 - I was created in iteration 1
Hello from thread 7 - I was created in iteration 2
Hello from thread 8 - I was created in iteration 3
Hello from thread 9 - I was created in iteration 4
Hello from thread 10 - I was created in iteration 5
I am thread 1. Created new thread (11) in iteration 6...
I am thread 1. Created new thread (12) in iteration 7...
Hello from thread 11 - I was created in iteration 6
Hello from thread 12 - I was created in iteration 7
What I've managed to code is this:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* PrintHello(int iteration)
{
printf("Hello from thread %u - I was created in iteration %d \n",
pthread_self(), iteration);
pthread_exit(NULL);
}
int main(void)
{
int rc;
pthread_t thread_id;
int tidMain;
int n, i;
tidMain = pthread_self();
printf("How many threads are there to be created?\n");
scanf("%d", &n);
for(i = 1; i <= n; i++) {
pthread_t thread_id;
rc = pthread_create(&thread_id, NULL, PrintHello, i);
printf("I am thread %u. Created new thread (%u) in iteration %d\n",
tidMain, thread_id, i);
if(rc)
{
printf("\n ERROR: return code from pthread_create is %d \n", rc);
exit(1);
}
if((i % 5) == 0) {
sleep(1);
}
}
pthread_exit(NULL);
}
The program does really print what I want to, and even sleeps and "breaks" the creation each 5 threads created; still, I don't know why, but when each created thread gets to be executed (after main thread has informed they have been created) in the 5-thread-printing-streak i want to, first thread that "greets" is the last created one. What i get from the console, i.e. when I ask it to create 8 threads, is this:
I am thread 3075630848. Created new thread (3075627840) in iteration 1
I am thread 3075630848. Created new thread (3067235136) in iteration 2
I am thread 3075630848. Created new thread (3058842432) in iteration 3
I am thread 3075630848. Created new thread (3050449728) in iteration 4
I am thread 3075630848. Created new thread (3042057024) in iteration 5
Hello from thread 3042057024 - I was created in iteration 5
Hello from thread 3050449728 - I was created in iteration 4
Hello from thread 3058842432 - I was created in iteration 3
Hello from thread 3067235136 - I was created in iteration 2
Hello from thread 3075627840 - I was created in iteration 1
I am thread 3075630848. Created new thread (3032480576) in iteration 6
I am thread 3075630848. Created new thread (3024087872) in iteration 7
I am thread 3075630848. Created new thread (3015695168) in iteration 8
Hello from thread 3015695168 - I was created in iteration 8
Hello from thread 3024087872 - I was created in iteration 7
Hello from thread 3032480576 - I was created in iteration 6
As long as I understand, it is first executing the last thread created. Why does this happen? Can I get it to execute the first created one first?
BTW: I'm running on Ubuntu
This is the point about concurrent programming. You can never make any assumptions about the order in which the threads execute. I, for example get the following output:
I am thread 639280960. Created new thread (630781696) in iteration 1
Hello from thread 630781696 - I was created in iteration 1
I am thread 639280960. Created new thread (622388992) in iteration 2
Hello from thread 622388992 - I was created in iteration 2
I am thread 639280960. Created new thread (613996288) in iteration 3
Hello from thread 613996288 - I was created in iteration 3
I am thread 639280960. Created new thread (536868608) in iteration 4
Hello from thread 536868608 - I was created in iteration 4
I am thread 639280960. Created new thread (526280448) in iteration 5
Hello from thread 526280448 - I was created in iteration 5
I am thread 639280960. Created new thread (517887744) in iteration 6
I am thread 639280960. Created new thread (509495040) in iteration 7
Hello from thread 509495040 - I was created in iteration 7
I am thread 639280960. Created new thread (501102336) in iteration 8
Hello from thread 501102336 - I was created in iteration 8
Hello from thread 517887744 - I was created in iteration 6
If I run it again, I might get a different output. Try it out on your own!
The Wikipedia Article about Concurrent computing, says the following:
The exact timing of when tasks in a concurrent system are executed
depend on the scheduling, and tasks need not always be executed
concurrently. For example, given two tasks, T1 and T2:
T1 may be executed and finished before T2 or vice versa (serial and sequential)
T1 and T2 may be executed alternately (serial and concurrent)
T1 and T2 may be executed simultaneously at the same instant of time (parallel and concurrent)
I suggest, you read some basic articles or literature about concurrency and parallelism.
It's a concurrent program. If you run your program several times, the order may be different even in the same host.
By the way, maybe it is better for you to see pthread API first before coding.
For pthread_create():
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
The 3rd argument is void *(*start_routine)(void *) rather than void *(start_routine)(int), and the 4th argument is void * rather than int.
The order in which threads are executed is undetermined. If you need a specific order than you have to use locks, mutexes and conditions to order their executuion to your requirements.
The order that you see is caused by your hardware and kernel and sometimes randomness. I'm assuming you have a single core cpu or the output would make little sense. When you create a thread your kernel simply schedules the thread to run at a later time and keeps executing the main thread. So you get messages for all 5 thread creations. Only when the main thread sleeps the kernel switches to the next thread ready to run. It seems to do this as FILO (first in - last out). That just happens to be what your kernel in your version on your hardware happens to do. Could change at any moment.
pOwl on the other hand seems to have multiple cores. So while the main thread creates thread the other core(s) already execute them. Or he simply has a different kernel.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
In scenario 2 why all threads are not getting triggered?
What is the problem with different mutex variable?
Scenario 1 :
I am creating four threads.Each threads were assigned to different cores all four threads are waiting for signal with same conditional and mutex variable.While passing broadcast signal with same conditional variable all threads were getting triggered.
#define _GNU_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<sched.h>
pthread_cond_t condVar=PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutexVar=PTHREAD_MUTEX_INITIALIZER;
void *thread1(void *ptr)
{
int iVar=1;
printf("Thread %d\n",iVar);
pthread_mutex_lock(&mutexVar);
pthread_cond_wait(&condVar,&mutexVar);
pthread_mutex_unlock(&mutexVar);
printf("Thread %d is unblocked...\n",iVar);
}
void *thread2(void *ptr)
{
int iVar=2;
printf("Thread %d\n",iVar);
pthread_mutex_lock(&mutexVar);
pthread_cond_wait(&condVar,&mutexVar);
pthread_mutex_unlock(&mutexVar);
printf("Thread %d is unblocked...\n",iVar);
}
void *thread3(void *ptr)
{
int iVar=3;
printf("Thread %d\n",iVar);
pthread_mutex_lock(&mutexVar);
pthread_cond_wait(&condVar,&mutexVar);
pthread_mutex_unlock(&mutexVar);
printf("Thread %d is unblocked...\n",iVar);
}
void *thread4(void *ptr)
{
int iVar=4;
printf("Thread %d\n",iVar);
pthread_mutex_lock(&mutexVar);
pthread_cond_wait(&condVar,&mutexVar);
pthread_mutex_unlock(&mutexVar);
printf("Thread %d is unblocked...\n",iVar);
}
int main()
{
int i,j=2;
pthread_t t[4];
cpu_set_t cpuset;
pthread_create(&t[0],0,thread1,0);
pthread_create(&t[1],0,thread2,0);
pthread_create(&t[2],0,thread3,0);
pthread_create(&t[3],0,thread4,0);
for(i=0;i<4;i++) //Assign dedicated core for each thread
{
CPU_ZERO(&cpuset);
CPU_SET(j,&cpuset);
if((pthread_setaffinity_np(t[i],sizeof(cpu_set_t),&cpuset))!=0)
perror("Set_affinity");
j+=2;
}
sleep(5);
pthread_cond_broadcast(&condVar);
while(1);
}
Output:
Thread 1
Thread 4
Thread 2
Thread 3
Thread 1 is unblocked...
Thread 4 is unblocked...
Thread 2 is unblocked...
Thread 3 is unblocked...
Scenario 2:
Instead of same mutex variable I have created different mutex to each thread.While passing broadcast signal among the four,only one thread is getting triggered remaining threads were waiting for signal.
Output for scenario 2 :
Thread 1
Thread 2
Thread 4
Thread 3
Thread 1 is unblocked...
Instead of same mutex variable I have created different mutex to each thread.While passing broadcast signal among the four,only one thread is getting triggered remaining threads were waiting for signal.
That's a misuse of condition variables and undefined behavior. Per the POSIX pthread_cond_wait() documentation:
When a thread waits on a condition variable, having specified a particular mutex to either the pthread_cond_timedwait() or the pthread_cond_wait() operation, a dynamic binding is formed between that mutex and condition variable that remains in effect as long as at least one thread is blocked on the condition variable. During this time, the effect of an attempt by any thread to wait on that condition variable using a different mutex is undefined.
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.
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!
This question already has answers here:
Wrong thread IDs in a multithreaded C program?
(2 answers)
Closed 8 years ago.
I compiled this code and the 99th threads that it's been created keeps creating more than one thread of number 99. Instead if i insert values from 1-10 or something small then the results are quite normal.
Here is the 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);
usleep(10000);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
int main()
{
int i=0,j=0;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
pthread_t thread[100];
for (i=0;i<100;i++)
{
j=i;
pthread_create(&thread[i],&attr,test,&j);
}
for (i=0;i<100;i++)
pthread_join(thread[i],NULL);
return 0;
}
i get:
..../*Normal Results*/
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
Why is this happening?
You need to keep all theadIds
int indexes[PTHREAD_COUNT];
for (i=0;i<100;i++) {
indexes[i] = i;
pthread_create(&thread[i], &attr, test, &indexes[i]);
}
Each thread is passed the same pointer to the same stack location (j) in your main thread. Without further synchronisation, its undefined when each thread will be scheduled and will run and access j before printing its value.
There are lots of ways you could print out a unique number from each thread, including
malloc a struct which includes (or is) this number in the main thread. Pass it to the child threads which are then responsible for freeing it
(Suggested by Brian Roche below) Declare an array of 100 ints, with values 0, 1, 2, etc. Pass the address of a different array item to each thread.
have each thread lock a mutex then copy/increment a global counter. The mutex could be passed into the thread or another global
pass a semaphore into each thread, signalling it once the number has been accessed. Wait on this semaphore in the main thread
Note that options 3 & 4 involve serialising startup of the threads. There's little point in running multiple threads if you do much of this!
i is the same address as j in your main code, and you sleep of 30 ms in the threads. So all threads have time to run until the first mutex call, then they all stop for (a little over) 30ms, and then print they have finished. Of course, i in the main loop is now 99, because you are finished with the pthread_join loop.
You need to have an array of "j" values [assuming you want all threads to run independently]. Or do something else. It all depends on what you are actually wanting to do.
you are passing the same memory location (&j) as the pointer to data a.
when threads start, they print out the value just assigned to j, which looks OK
But then only one get the lock and went to sleep, all others thus blocked. when the nightmare is over, memory location "a", of course, has a int value 99.