0

I'm writing a program in c on linux using gcc. If I'm not using that sleep statement it will print "thread created" 2,3 or 4 number of times randomly. Can anyone explain me this behavior? //the following code is just a sample, i know is not really useful to create a thread just to print a string :)

void* makeRequest(void* arg) {
    printf("Thread created\n");
}

int main(){
   pthread_t thr[10];
   for(i=0; i<3; i++){  
       pthread_create(&thr[i], 0, makeRequest, &i);
       sleep(1);
    }
 }

p.s. I included pthread.h and the compile option -pthread

4 Answers4

4

You should join all threads that you create, ending main as you do exits the whole process.

Alternatively you could end your main with pthread_exit.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • so the pthread join must be done after that for statement? (my program is quite complex and that "for" statement must be executed infinitely many times because it waits for client requests; when a client request exists it will create 3 threads) `while(1){for(i=0; i<3; i++){ pthread_create(&thr[i], 0, makeRequest, &i); sleep(1); }}` – 55651909-089b-4e04-9408-47c5bf Dec 28 '12 at 13:43
  • 2
    You just have to ensure that your `main` doesn't end before any of your other threads. So, yes, the join has to be somewhere between the creation of the threads in the `for` loop and the termination of `main`. – Jens Gustedt Dec 28 '12 at 15:04
2

In addition to other remarks,

 pthread_create(&thr[i], 0, makeRequest, &i);

is incorrect, because i is a local variable, so &i is the same pointer on all your calls to pthread_create

You generally should make the data pointer to your thread routine -here the thread routine is makeRequest either a static pointer, or a unique pointer (unique for each thread); in practice, make it a pointer to some malloc-ed memoory.

A better practice would be declare some struct my_thread_data_st, to uniquely allocate it in the heap with

struct my_thread_data_st* td = malloc(sizeof(struct my_thread_data_st));
if (!td) perror("malloc td"), exit(EXIT_FAILURE);
memset (td, 0, sizeof(struct my_thread_data_st));
// fill td appropriately, then
pthread_create(&thr[i], 0, makeRequest, td);

Or you could have an array of e.g. int-s, e.g. int num[4];, initialize it appropriately, then pthread_create(&thr[i], 0, makeRequest, &num[i]);

Of course, if td is heap-allocated thru malloc, don't forget to free it at the appropriate time, e.g. after the thread ended (e.g. after having pthread_join-ed it). You might be also interested by Boehm's GC and use GC_malloc instead of malloc (then, don't bother about freeing memory, the GC will do it).

If the threads are accessing a shared data, you should serialize access to it with some [global or static] mutex (using pthread_mutex_lock & pthread_mutex_unlock)

Don't forget to call pthread_join on all your threads before exiting -e.g. returning from main.

I suggest reading some pthreads tutorial and some book on advanced linux programming.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

You need:

for(i = 0; i < 3; i++)
{
   pthread_join(thr[i], NULL);
}

As you have written it, there is nothing waiting for your threads to finish before main returns and exits the whole process, killing the threads.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
1

First use join: and no need to send &i if you don't use it.

print "thread created" 2,3 or 4 number of times randomly.

When main thread dies all child thread also die. so you need to wait in join.

randomly.: because we don't know in thread context switching which will get chance. it may be main-thread or child threads.

for(i=0; i<3; i++){  
       pthread_create(&thr[i], 0, makeRequest, &i);   
}

for(i=0; i<3; i++){  
       pthread_join(thr[i], NULL);
}

Second use -lpthread not -pthread

$ gcc file.c -lpthread -o output      

EDITED

-pthread Adds support for multithreading with the "pthreads" library. This option sets flags for both the preprocessor and linker: Jens Gustedt comment

Difference between -pthread and -lpthread

Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • thanks for -lpthread suggestion, i will read more about this //i know I don't need to send that "i" , but as i said before this is just a sample,(the whole code has about 500 lines) – 55651909-089b-4e04-9408-47c5bf Dec 28 '12 at 13:50
  • @nickNatra but i don't think `"thread created"` printed 4-times, it may be max 3-times. – Grijesh Chauhan Dec 28 '12 at 13:56
  • 1
    @GrijeshChauhan, `-pthread` is the correct option for gcc. It does more than would `-lpthread`: "`-pthread` Adds support for multithreading with the "pthreads" library. This option sets flags for both the preprocessor and linker." – Jens Gustedt Dec 28 '12 at 15:07
  • @JensGustedt : Oh..I doesn't know about -pthread :(. I did mistake then...But I didn't find this option in google-search. – Grijesh Chauhan Dec 28 '12 at 15:20