Flora Biletsiou
Flora Biletsiou

Reputation: 479

Thread created but doesn't work accordingly

I am facing a problem with a code I am writing but I really can't recognize what it's causing it, so a helping hand would be much appreciated.
The case is simple
--> giving number of threads as argument from the command line
--> creating N threads , with parameter
--> each thread says hello and it's parameter and exits
So here is my code:

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

void* client_func(void *arg) {
    int myid = *((int *) arg);
    printf("hello!\n my id is %d\n",myid);
    return NULL;
}

int main(int argc, char *argv[] ){
    int i,j = 0;
    int N_cust = atoi(argv[1]);

    //creation of client threads
    pthread_t tid[N_cust];
    int err;

    for (i = 0; i < N_cust; i++){
        int *id = malloc(sizeof(*id));
        err = pthread_create(&tid[i], NULL, &client_func,(void *) id);
        if(err !=0){
            perror("pthread_create() error");
            exit(1);
       }
       else{
           printf("\n Thread created successfully\n");
       }
    }

    return 0;
}

I was waiting to get as a result the "hello" messages with the id of the thread but instead i get:

$ ./proj1 3 5

Thread created successfully
Thread created successfully
Thread created successfully

I am new to threads, but from my understanding the thread is not executing at all . Any help in what I am doing wrong? Thanks

Upvotes: 0

Views: 101

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754820

As I noted in a comment, you have a number of problems in your code:

  • You allocate space for the id pointer to point at, but you never set it to any known value.
  • Your thread function also forgets to free the allocated memory it is given.
  • Your main program should probably also wait for the child threads to complete with pthread_join() before it exits (via return 0;).

Calling exit() — even indirectly by returning from main() — means that the process (and all the threads in it) are terminated immediately. You could instead use pthread_exit(0); in main() instead of return 0; and you would get your threads to run to completion.

Here are two variants of your code with these problems fixed. Variant 1 (pthr41.c) has the main thread exit with pthread_exit(0);. Variant 2 (pthr43.c) has the main thread use pthread_join(). There is a smattering of error detection added.

pthr41.c

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

static void *client_func(void *arg)
{
    int myid = *((int *)arg);
    printf("\nhello! my id is %d\n", myid);
    free(arg);
    return NULL;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s numthreads\n", argv[0]);
        return 1;
    }
    int N_cust = atoi(argv[1]);
    if (N_cust <= 0 || N_cust > 1000)
    {
        fprintf(stderr, "%s: number of threads %s out of range 1..1000\n", argv[0], argv[1]);
        return 1;
    }

    // creation of client threads
    pthread_t tid[N_cust];

    for (int i = 0; i < N_cust; i++)
    {
        int *id = malloc(sizeof(*id));
        *id = i + 1;
        int err = pthread_create(&tid[i], NULL, client_func, id);
        if (err != 0)
        {
            perror("pthread_create() error");
            exit(1);
        }
        else
        {
            printf("\nThread %d created successfully\n", i + 1);
        }
    }

    printf("\nMain thread exits\n");
    pthread_exit(0);
    //return 0;
}

Sample output

It took a number of runs before I got this output, but this shows thread 4 finishing after the main thread:

$ pthr41 4

Thread 1 created successfully

Thread 2 created successfully

hello! my id is 1

hello! my id is 2

hello! my id is 3

Thread 3 created successfully

Thread 4 created successfully

Main thread exits

hello! my id is 4
$

pthr43.c

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static void *client_func(void *arg)
{
    int myid = *((int *)arg);
    printf("\nhello! my id is %d\n", myid);
    free(arg);
    return NULL;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s numthreads\n", argv[0]);
        return 1;
    }
    int N_cust = atoi(argv[1]);
    if (N_cust <= 0 || N_cust > 1000)
    {
        fprintf(stderr, "%s: number of threads %s out of range 1..1000\n", argv[0], argv[1]);
        return 1;
    }

    // creation of client threads
    pthread_t tid[N_cust];

    for (int i = 0; i < N_cust; i++)
    {
        int *id = malloc(sizeof(*id));
        *id = i + 1;
        int err = pthread_create(&tid[i], NULL, client_func, id);
        if (err != 0)
        {
            perror("pthread_create() error");
            exit(1);
        }
        else
        {
            printf("\nThread %d created successfully\n", i + 1);
        }
    }

    for (int i = 0; i < N_cust; i++)
    {
        void *vp;
        int err = pthread_join(tid[i], &vp);
        if (err != 0)
        {
            fprintf(stderr, "%s: error %d (%s) from joining thread %d\n",
                    argv[0], err, strerror(err), i + 1);
        }
        else
            assert(vp == NULL);
    }
    printf("All threads complete\n");

    //pthread_exit(0);
    return 0;
}

Sample output

$ pthr43 4

Thread 1 created successfully

hello! my id is 1

hello! my id is 2

Thread 2 created successfully

Thread 3 created successfully

hello! my id is 3

Thread 4 created successfully

hello! my id is 4
All threads complete
$

Upvotes: 1

Related Questions