I'm fairly new to threads in C. For this program I need to declare a thread which I pass in a for loop thats meant to print out the printfs from the thread.
I can't seem to get it to print in correct order. Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 16
void *thread(void *thread_id) {
int id = *((int *) thread_id);
printf("Hello from thread %d\n", id);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
int code = pthread_create(&threads[i], NULL, thread, &i);
if (code != 0) {
fprintf(stderr, "pthread_create failed!\n");
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
//gcc -o main main.c -lpthread
That's the classic example of understanding multi-threading.
The threads are running concurrently, scheduled by OS scheduler.
There is no such thing as "correct order" when we are talking about running in parallel.
Also, there is such thing as buffers flushing for stdout output. Means, when you "printf" something, it is not promised it will happen immediately, but after reaching some buffer limit/timeout.
Also, if you want to do the work in the "correct order", means wait until the first thread finishes it's work before staring next one, consider using "join":
http://man7.org/linux/man-pages/man3/pthread_join.3.html
UPD:
passing pointer to thread_id is also incorrect in this case, as a thread may print id that doesn't belong to him (thanks Kevin)
Related
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int count = 0;
pthread_mutex_t MUTEX = PTHREAD_MUTEX_INITIALIZER;
void* func1(void* a){
pthread_mutex_lock(&MUTEX);
for(;count < 4;count++){
printf("LOOP 1: %d\n",count);
sleep(1);
}
pthread_mutex_unlock(&MUTEX);
}
void* func2(void* a){
pthread_mutex_lock(&MUTEX);
for(;count < 8;count++){
printf("LOOP 2: %d\n",count);
sleep(1);
}
pthread_mutex_unlock(&MUTEX);
}
int main(){
pthread_t tid[2];
int a = 1;
int status;
if(pthread_create(tid,NULL,func1,(void*)&a))
printf("func1 error\n");
if(pthread_create(tid+1,NULL,func2,(void*)&a))
printf("func2 error\n");
//pthread_join(*tid, (void *) &status);
//pthread_join(*(tid+1), (void *) &status);
}
simple code for testing how thread and mutex works.
If I run the code, it just terminates without showing anything (sometimes just one line "LOOP 1: 0")
If I uncomment
//pthread_join(*tid, (void *) &status);
//pthread_join(*(tid+1), (void *) &status);
then it works well.
HOW this happens? someone please explain
pthread_join(t,...) waits until the thread t is finished. That is to say, the ...join call does not return until t is finished.
So, your question really is about what happens in a C program if the main() function returns while threads that were created by pthread_create(...) still are running.
The answer (at least, for some versions of C)* is that after main() returns some value, v, the library then calls exit(v). You can look in the man pages or, in the documentation for whatever system you're running on to find out what else exit(...) does, but one of the things that it does is, it terminates the entire process, including all of its threads.
* I am not 100% certain that every version of C and the C standard libraries behave in this way, but it's the behavior that I am accustomed to expect.
Note also that this behavior is different from modern C++ where, std::thread instances can continue to run even after main(...) has returned.
Hi fellow programmers,
I wanted to write a simple multi-threaded program in C with pthread, but somehow the pthread_join seems to hang.
It seems happens not always, sometimes everything is running fine, next time it't hanging againg, usually on the first thread.
I already minimized the code to the bare minimum, so that i can exclude other problems. In the full code the threads did some computations, of course. But the problems still persists even with this very reduced code. And on more than one machine, with different OS'es.
strace shows me that the hanging has something to do with a FUTEX_WAIT, the full last lines:
write(1, "Joining Thread 0...\n", 20Joining Thread 0...
) = 20
futex(0x7fff61718a20, FUTEX_WAIT, 1634835878, NULL
I tried to debug it with gdb, but my poor debugging stills are very limited, especially with multi-threaded programs.
I also tried to compile it using different C-standards (C99 and Ansi) and both pthread parameters (-lpthread, -pthread), but the problem still persists.
The (reduced) code monte2.c:
#include <stdio.h>
#include <pthread.h>
void *monte(struct MonteArgs *args) {
pthread_exit(NULL);
}
int main(int argc, char **argv) {
int numThreads, numSamples;
int i;
if (argc != 3) {
printf("Usage: monte threads samples\n");
exit(1);
}
numThreads = atoi(argv[1]);
pthread_t threads[numThreads];
numSamples = atoi(argv[2]);
for (i=0; i<numThreads; i++) {
if (pthread_create(&threads[i], NULL, monte, NULL)) {
printf("Error Creating Thread %d!\n", i);
return 1;
}
}
for (i=0; i<numThreads; i++){
printf("Joining Thread %d...\n", i);
pthread_join(&threads[i], NULL);
}
printf("End!\n");
fflush(stdout);
return(0);
}
I compile with
gcc monte2.c -lpthread -o monte
and run with
./monte2 3 100
where the first argument is the number of threads, and the second is actually not needed for the reduced code.
It's been a while since I've done multi-threaded C, but you shouldn't ignore compiler warnings :-). Compile with -Wall.
You should be seeing a warning like this:
note: expected 'pthread_t' but argument is of type 'pthread_t *'
int WINPTHREAD_API pthread_join(pthread_t t, void **res);
You are passing a pthread_t* when you should be passing pthread_t.
Refer to the pthread_join docs: http://man7.org/linux/man-pages/man3/pthread_join.3.html
One final question for the evening. I have a homework question that I cannot seem to solve, and after spending the better part of the night on it, I'll ask it here.
The problem is a program that is to calculate the Fibonacci sequence given an integer input at the command line (./foo.out 15, for example, and it will calculate the first 15 Fibonacci numbers). The additional parameters are as follows:
1.) It must use two POSIX threads, a parent thread and a child thread.
2.) It must share data (an array) between them.
Currently, the function is breaking when program control passes back to the parent thread. All I am getting is a completely non-descriptive segfault. As can be seen below, I have it outputting at every possible change in control.
Code:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
void *fibonacci(void *param, int numbers[]);
void *runner(void *param);
int main(int argc, char *argv[])
{
pthread_t tid;
pthread_attr_t attr;
if ( argc != 2)
{
fprintf(stderr, "Usage: 426.out <integer value> \n");
return -1;
}
if (atoi(argv[1]) < 0)
{
fprintf(stderr, "Argument must be non-negative\n");
return -2;
}
pthread_attr_init(&attr);
pthread_create(&tid, &attr, runner, argv[1]);
pthread_join(tid,NULL);
return 0;
}
void *fibonacci(void *param, int numbers[])
{
int it, IT_MAX;
printf("Entering Child Thread:\n");
IT_MAX = atoi(param);
numbers[0] = 0;
numbers[1] = 1;
for (it = 2; it < IT_MAX; ++it)
{
numbers[it] = (numbers[it - 1] + numbers[it - 2]);
}
for (it = 0; it < IT_MAX; ++it)
{
printf("%d\n", numbers[it]);
}
printf("Exiting Child Function.\n");
}
void *runner(void *param)
{
int it, IT_MAX;
int numbers[IT_MAX];
pthread_t tid;
pthread_attr_t attr;
printf("Entering Parent Thread:\n");
pthread_attr_init(&attr);
pthread_create(&tid, &attr, fibonacci(param, numbers), NULL);
pthread_join(tid, NULL);
IT_MAX = atoi(param);
for (it = 0; it < IT_MAX; it++)
{
printf("%d\n", numbers[it]); // I suspect the program breaks here
// It produces a segfault rather than this
}
printf("Leaving Parent Thread\n");
}
The question I have, if it is not clear from above, is what am I doing wrong. I am using gcc, and have been using the -Wall -Werror and -lpthread. -Werror keeps throwing "Control Structure going to end of non-void function", but nothing has anything to say about what can be causing the segfault. As before, I looked for the last hour for a question or article that addresses this, so if this is a dupe, please point me to the question or article in which it is addressed. Thanks to anyone in advance for their help.
One of your problems is in this line:
pthread_create(&tid, &attr, fibonacci(param, numbers), NULL);
Instead of starting a thread with the fibonacci() function, this calls the fibbonacci() function in the current thread and passes the result to pthread_create() as the thread start function. fibonacci() doesn't return a function pointer, so this new thread will crash the program.
You need to just pass fibonacci as the third parameter.
Futhermore, fibonacci() must be declared as void *fibonacci(void *) in order to be used as a thread start function. If you want to pass two parameters, you'll need to place them into a struct and pass a pointer to that.
This pair of lines is also problematic:
int it, IT_MAX;
int numbers[IT_MAX];
IT_MAX is an uninitialised variable, and you use it here to define the size of the numbers[] array. That could also be leading to your crash.
This line
pthread_create(&tid, &attr, fibonacci(param, numbers), NULL);
does not pass the address of fibonacci() to pthread_create() but calls fibonacci(param, numbers)and passes the result returned to pthread_create() as 3rd argument.
I just want my main thread to wait for any and all my (p)threads to complete before exiting.
The threads come and go a lot for different reasons, and I really don't want to keep track of all of them - I just want to know when they're all gone.
wait() does this for child processes, returning ECHILD when there are no children left, however wait does not (appear to work with) (p)threads.
I really don't want to go through the trouble of keeping a list of every single outstanding thread (as they come and go), then having to call pthread_join on each.
As there a quick-and-dirty way to do this?
Do you want your main thread to do anything in particular after all the threads have completed?
If not, you can have your main thread simply call pthread_exit() instead of returning (or calling exit()).
If main() returns it implicitly calls (or behaves as if it called) exit(), which will terminate the process. However, if main() calls pthread_exit() instead of returning, that implicit call to exit() doesn't occur and the process won't immediately end - it'll end when all threads have terminated.
http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_exit.html
Can't get too much quick-n-dirtier.
Here's a small example program that will let you see the difference. Pass -DUSE_PTHREAD_EXIT to the compiler to see the process wait for all threads to finish. Compile without that macro defined to see the process stop threads in their tracks.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
static
void sleep(int ms)
{
struct timespec waittime;
waittime.tv_sec = (ms / 1000);
ms = ms % 1000;
waittime.tv_nsec = ms * 1000 * 1000;
nanosleep( &waittime, NULL);
}
void* threadfunc( void* c)
{
int id = (int) c;
int i = 0;
for (i = 0 ; i < 12; ++i) {
printf( "thread %d, iteration %d\n", id, i);
sleep(10);
}
return 0;
}
int main()
{
int i = 4;
for (; i; --i) {
pthread_t* tcb = malloc( sizeof(*tcb));
pthread_create( tcb, NULL, threadfunc, (void*) i);
}
sleep(40);
#ifdef USE_PTHREAD_EXIT
pthread_exit(0);
#endif
return 0;
}
The proper way is to keep track of all of your pthread_id's, but you asked for a quick and dirty way so here it is. Basically:
just keep a total count of running threads,
increment it in the main loop before calling pthread_create,
decrement the thread count as each thread finishes.
Then sleep at the end of the main process until the count returns to 0.
.
volatile int running_threads = 0;
pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER;
void * threadStart()
{
// do the thread work
pthread_mutex_lock(&running_mutex);
running_threads--;
pthread_mutex_unlock(&running_mutex);
}
int main()
{
for (i = 0; i < num_threads;i++)
{
pthread_mutex_lock(&running_mutex);
running_threads++;
pthread_mutex_unlock(&running_mutex);
// launch thread
}
while (running_threads > 0)
{
sleep(1);
}
}
If you don't want to keep track of your threads then you can detach the threads so you don't have to care about them, but in order to tell when they are finished you will have to go a bit further.
One trick would be to keep a list (linked list, array, whatever) of the threads' statuses. When a thread starts it sets its status in the array to something like THREAD_STATUS_RUNNING and just before it ends it updates its status to something like THREAD_STATUS_STOPPED. Then when you want to check if all threads have stopped you can just iterate over this array and check all the statuses.
Don't forget though that if you do something like this, you will need to control access to the array so that only one thread can access (read and write) it at a time, so you'll need to use a mutex on it.
you could keep a list all your thread ids and then do pthread_join on each one,
of course you will need a mutex to control access to the thread id list. you will
also need some kind of list that can be modified while being iterated on, maybe a std::set<pthread_t>?
int main() {
pthread_mutex_lock(&mutex);
void *data;
for(threadId in threadIdList) {
pthread_mutex_unlock(&mutex);
pthread_join(threadId, &data);
pthread_mutex_lock(&mutex);
}
printf("All threads completed.\n");
}
// called by any thread to create another
void CreateThread()
{
pthread_t id;
pthread_mutex_lock(&mutex);
pthread_create(&id, NULL, ThreadInit, &id); // pass the id so the thread can use it with to remove itself
threadIdList.add(id);
pthread_mutex_unlock(&mutex);
}
// called by each thread before it dies
void RemoveThread(pthread_t& id)
{
pthread_mutex_lock(&mutex);
threadIdList.remove(id);
pthread_mutex_unlock(&mutex);
}
Thanks all for the great answers! There has been a lot of talk about using memory barriers etc - so I figured I'd post an answer that properly showed them used for this.
#define NUM_THREADS 5
unsigned int thread_count;
void *threadfunc(void *arg) {
printf("Thread %p running\n",arg);
sleep(3);
printf("Thread %p exiting\n",arg);
__sync_fetch_and_sub(&thread_count,1);
return 0L;
}
int main() {
int i;
pthread_t thread[NUM_THREADS];
thread_count=NUM_THREADS;
for (i=0;i<NUM_THREADS;i++) {
pthread_create(&thread[i],0L,threadfunc,&thread[i]);
}
do {
__sync_synchronize();
} while (thread_count);
printf("All threads done\n");
}
Note that the __sync macros are "non-standard" GCC internal macros. LLVM supports these too - but if your using another compiler, you may have to do something different.
Another big thing to note is: Why would you burn an entire core, or waste "half" of a CPU spinning in a tight poll-loop just waiting for others to finish - when you could easily put it to work? The following mod uses the initial thread to run one of the workers, then wait for the others to complete:
thread_count=NUM_THREADS;
for (i=1;i<NUM_THREADS;i++) {
pthread_create(&thread[i],0L,threadfunc,&thread[i]);
}
threadfunc(&thread[0]);
do {
__sync_synchronize();
} while (thread_count);
printf("All threads done\n");
}
Note that we start creating the threads starting at "1" instead of "0", then directly run "thread 0" inline, waiting for all threads to complete after it's done. We pass &thread[0] to it for consistency (even though it's meaningless here), though in reality you'd probably pass your own variables/context.
The following code is a simple thread game, that switches between threads causing the timer to decrease.
It works fine for 3 threads, causes and Abort(core dumped) for 4 threads, and causes a seg fault for 5 or more threads.
Anyone have any idea why this might be happening?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <assert.h>
int volatile num_of_threads;
int volatile time_per_round;
int volatile time_left;
int volatile turn_id;
int volatile thread_running;
int volatile can_check;
void * player (void * id_in){
int id= (int)id_in;
while(1){
if(can_check){
if (time_left<=0){
break;
}
can_check=0;
if(thread_running){
if(turn_id==id-1){
turn_id=random()%num_of_threads;
time_left--;
}
}
can_check=1;
}
}
pthread_exit(NULL);
}
int main(int argc, char *args[]){
int i;
int buffer;
pthread_t * threads =(pthread_t *)malloc(num_of_threads*sizeof(pthread_t));
thread_running=0;
num_of_threads=atoi(args[1]);
can_check=0;
time_per_round = atoi(args[2]);
time_left=time_per_round;
srandom(time(NULL));
//Create Threads
for (i=0;i<num_of_threads;i++){
do{
buffer=pthread_create(&threads[i],NULL,player,(void *)(i+1));
}while(buffer == EAGAIN);
}
can_check=1;
time_left=time_per_round;
turn_id=random()%num_of_threads;
thread_running=1;
for (i=0;i<num_of_threads;i++){
assert(!pthread_join(threads[i], NULL));
}
return 0;
}
See below on why you should not depend on volatile in pthreads. However, your specific problem is probably because you malloc your pthread array, based on the num_of_threads variable before you've actually set num_of_thread from argv[]:
pthread_t *threads = (pthread_t *)malloc (num_of_threads * sizeof (pthread_t));
thread_running = 0;
num_of_threads = atoi (args[1]);
So there's a very good chance you're writing beyond the end of the threads array. The num_of_threads variable will probably be zero on start-up which means you're not allocating what you think you are. Move the allocation to after the extraction of the arguments and that should fix it.
And now, for your viewing pleasure :-), my original rant on the unsafe use of volatile, which I still stand by.
Do not rely on volatile to protect your shared variables. The correct way to do this is with the pthread_mutex_blab_blah_blah calls.
Of particular note, examine this code segment:
if (can_check) {
if (time_left <= 0) {
break;
}
// URK!!
can_check=0;
URK!! is the point where your current thread may be switched out and another run, leading to the possibility that two threads can be running a critical section of code.
My advice is to forget the can_check altogether and just protect all the shared variables with a mutex, something like (from memory):
void *player (void * id_in) {
int id = (int)id_in;
while (1) {
pthread_mutex_lock (&mutex);
if (time_left <= 0) {
pthread_mutex_unlock (&mutex);
break;
}
if (thread_running) {
if (turn_id == id-1) {
turn_id = random() % num_of_threads;
time_left--;
}
}
pthread_mutex_unlock (&mutex);
}
pthread_exit(NULL);
}
Then put at file-level:
pthread_mutexattr_t mutexattr; // prob. not needed at file level.
pthread_mutex_t mutex;
and, in main, before starting any other threads:
pthread_mutexattr_init (&mutexattr);
// Change attributes if needed.
pthread_mutex_init (&mutex, &mutex_attr);
// Then run all you other stuff here, make sure you've joined with all threads.
pthread_mutex_destroy (&mutex);
Oh yeah, although I haven't done it, you should also check the return codes for all those mutex calls. I'm not going to add that since it'll clog up the answer with unnecessary detail, but it's good practice.