Computernerd
Computernerd

Reputation: 7766

pthread_create does not execute properly

I am learning about multi-thread programs and am expecting the following snippet of code to be an infinite loop of printing "foo" instead nothing happens

Expectations :

foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo

Reality :

It is as though the thread is not even being created , what am i doing wrong ??? How do i create a thread which will execute whatever function is assigned to it

Source code

#include <pthread.h>
#include <stdlib.h>

#include <stdio.h>

#include <string.h>
#include <iostream>

void* print(void*);

struct threadInfo
{

    int threadID;
    int threadNo;

};

int main()
{
    pthread_t thread[3];
    bool cont = false;
    int i = 1;
    int max = 3;

    while ( cont == false )
    {
        if ( i <= max )
        {
            threadInfo t_info;
            t_info.threadID = i ;
            t_info.threadNo = i ;
            pthread_create(&thread[i-1],NULL,print,(void*)&t_info);

            i++;
        }
    }   





}

void* print(void* arg)
{
  std::cout << "Foo" ; 
  pthread_exit(NULL);
}

The following piece of code is compiled on Ubuntu command line with the following command

g++ test.cpp -o test -lpthread

Upvotes: 0

Views: 400

Answers (5)

kuroi neko
kuroi neko

Reputation: 8641

My oh my... Where to start ?

The reason why you don't see a thing has been given by Joachim Pileborg: the threads are created all right and do their job, but since your main program never exits and nobody ever outputs a line feed, the line-buffered output is never flushed.

Your main program is wasting CPU looping on a flag that will never be changed. Trying to synchronize threads with flags is extremely bad, despite the stupid new C++11 extensions that make atomic variables the alpha and omega of thread programming.
You must use some kind of synchro to wait for thread terminations. The most usual mechanism is pthread_join.

Passing the same instance of parameters to each instance of your thread creates a perfect race condition. You have no guarantee the thread will read the parameters in your intended order (i.e. before the main loop changes them to prepare for the next thread launch). You should pass each thread its own private instance of t_info (or setup some kind of synchronization mechanism over this structure).

Even after fixing all these problems, you should expect only 3 "Foo" since each thread exits after a single print.

And since you don't serialize the cout accesses (i.e. you don't protect them with some kind of synchro object like a mutex), it is possible the outputs of your various threads will be mixed at random (i.e. you could see something like "FoFFooooo").

Upvotes: 1

jpmuc
jpmuc

Reputation: 1154

There is nothing wrong with pthreads. If you want to ensure that sequence in the output, you need to enclose the print out line with a lock and a flush, so that you enforce that,

1. A thread only finishes once the message has actually been printed out
2. Threads wait for each other so that no two threads write to the output at the same time

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409136

There nothing printed because the output buffers are not flushed.

In the print function, do e.g.

std::cout << "Foo" << std::flush;

Upvotes: 1

alk
alk

Reputation: 70883

The main thread probably ends (and tremrinates all other thread with this) before any other thread has printed out anything.

To fix this either make the main thread join loopig around (pthread_join() for all thread-ids created) on all other thread before ending, or end the main thread using pthread_exit().


Also passing the address of the same instance of struct threadInfo the each tread (that is: (void*)&t_info) most probably is not what you want.

Upvotes: 0

erenon
erenon

Reputation: 19118

The threads are created, but before they could run, the main thread exits, and your program terminates (it's also UB). You have to wait for your threads: pthread_join

The while ( cont == false ) is not needed.

Upvotes: 2

Related Questions