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.
Related
here im trying to, use a circular queish thing for my insert and remove methods, as well as use the insert and remove functions for synchronization
im compiling with gcc file.c -lpthread -lrt and running with ./a.out 50 1 1.
upon running my producer produces and outputs correctly
producer thread #0
consumer thread #0
producer produced 7
but for whatever reason i cannot get my consumer to output,
i have tried putting my return 0; for each functions outside the locks and semaphores and it does indeed output consumer, but too many times when it should only run once per thread,
its also using a standard counting semaphore 2 of them as well as a single mutex lock
this is what happens when i move the return below the locks
producer thread #0
consumer thread #0
producer produced 7
consumer consumed 7
producer produced 5
producer produced 5
consumer consumed 5
consumer consumed 2
producer produced 7
producer produced 4
consumer consumed 7
consumer consumed 4
producer produced 6
consumer consumed 6
producer produced 1
consumer consumed 1
producer produced 9
consumer consumed 9
producer produced 2
consumer consumed 2
producer produced 6
consumer consumed 6
when in reality there should if i run ./a.out 50 1 1 there should only be one producer and one consumer
update: working on a new version on this so taking back my previous code, will post new version
In the functions insert_item() and remove_item(), returning (end of execution of the functions) happens before executing pthread_mutex_unlock(). This will prevent them from unlocking and prevent 2nd or later execution of the functions.
Instead of this, you should store the value to return in a variable and return that after unlocking. This can be done like this:
int insert_item(buffer_item item)
{
int ret;
sem_wait(&empty);
pthread_mutex_lock(&lock);
if (size_check < BUFFER_SIZE)
{
buffer[insertBounds_check++] = item;
size_check++;
ret = 0;
}
else
{
ret = -1;
}
pthread_mutex_unlock(&lock);
sem_post(&full);
return ret;
}
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);
}
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.
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.
My question is similar to How do I check if a thread is terminated when using pthread?. but i did not quite get an answer.
My problem is...I create a certain number of threads say n. As soon as main detects the exit of any one thread it creates another thread thus keeping the degree of concurrency as n and so on.
How does the main thread detect the exit of a thread. pthread_join waits for a particular thread to exit but in my case it can be any one of the n threads.
Thanks
Most obvious, without restructuring your code as aix suggests, is to have each thread set something to indicate that it has finished (probably a value in an array shared between all threads, one slot per worker thread), and then signal a condition variable. Main thread waits on the condition variable and each time it wakes up, handle all threads that have indicated themselves finished: there may be more than one.
Of course that means that if the thread is cancelled you never get signalled, so use a cancellation handler or don't cancel the thread.
There are several ways to solve this.
One natural way is to have a thread pool of fixed size n and have a queue into which the main thread would place tasks and from which the workers would pick up tasks and process them. This will maintain a constant degree of concurrency.
An alternative is to have a semaphore with the initial value set to n. Every time a worker thread is created, the value of the semaphore would need to be decremented. Whenever a worker is about to terminate, it would need to increment ("post") the semaphore. Now, waiting on the semaphore in the main thread will block until there's fewer than n workers left; a new worker thread would then be spawned and the wait resumed. Since you won't be using pthread_join on the workers, they should be detached (pthread_detach).
If you want to be informed of a thread exiting (via pthread_exit or cancellation), you can use a handler with pthread_cleanup_push to inform the main thread of the child exiting (via a condition variable, semaphore or similar) so it can either wait on it, or simply start a new one (assuming the child is detached first).
Alternately, I'd suggest having the threads wait for more work (as suggested by #aix), rather than ending.
If your parent thread needs to do other other things, then it can't just constantly be blocking on pthread_join, You will need a way to send a message to the main thread from the child thread to tell it to call pthread_join. There are a number of IPC mechanisms that you could use for this.
When a child thread has done it's work, it would then send some sort of message to the main thread through IPC saying "I completed my job" and also pass its own thread id, then the main thread knows to call pthread_join on that thread id.
One easy way is to use a pipe as a communication channel between the (worker) threads and your main thread. When a thread terminates it writes its result (thread id in the following example) to the pipe. The main thread waits on the pipe and reads the thread result from it as soon as it becomes available.
Unlike mutex or semaphore, a pipe file descriptor can be easily handled by the application main event loop (such as libevent). The writes from different threads to the same pipe are atomic as long as they write PIPE_BUF or less bytes (4096 on my Linux).
Below is a demo that creates ten threads each of which has a different life span. Then the main thread waits for any thread to terminate and prints its thread id. It terminates when all ten threads have completed.
$ cat test.cc
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
void* thread_fun(void* arg) {
// do something
unsigned delay = rand() % 10;
usleep(delay * 1000000);
// notify termination
int* thread_completed_fd = static_cast<int*>(arg);
pthread_t thread_id = pthread_self();
if(sizeof thread_id != write(*thread_completed_fd, &thread_id, sizeof thread_id))
abort();
return 0;
}
int main() {
int fd[2];
if(pipe(fd))
abort();
enum { THREADS = 10 };
time_t start = time(NULL);
// start threads
for(int n = THREADS; n--;) {
pthread_t thread_id;
if(pthread_create(&thread_id, NULL, thread_fun, fd + 1))
abort();
std::cout << time(NULL) - start << " sec: started thread " << thread_id << '\n';
}
// wait for the threads to finish
for(int n = THREADS; n--;) {
pthread_t thread_id;
if(sizeof thread_id != read(fd[0], &thread_id, sizeof thread_id))
abort();
if(pthread_join(thread_id, NULL)) // detached threads don't need this call
abort();
std::cout << time(NULL) - start << " sec: thread " << thread_id << " has completed\n";
}
close(fd[0]);
close(fd[1]);
}
$ g++ -o test -pthread -Wall -Wextra -march=native test.cc
$ ./test
0 sec: started thread 140672287479552
0 sec: started thread 140672278759168
0 sec: started thread 140672270038784
0 sec: started thread 140672261318400
0 sec: started thread 140672252598016
0 sec: started thread 140672243877632
0 sec: started thread 140672235157248
0 sec: started thread 140672226436864
0 sec: started thread 140672217716480
0 sec: started thread 140672208996096
1 sec: thread 140672208996096 has completed
2 sec: thread 140672226436864 has completed
3 sec: thread 140672287479552 has completed
3 sec: thread 140672243877632 has completed
5 sec: thread 140672252598016 has completed
5 sec: thread 140672261318400 has completed
6 sec: thread 140672278759168 has completed
6 sec: thread 140672235157248 has completed
7 sec: thread 140672270038784 has completed
9 sec: thread 140672217716480 has completed