S.Sot
S.Sot

Reputation: 323

Getting a segmentation fault after a thread completes it's job

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

void *print_n(int);

int main()
{
    while (1)
    {
        pthread_t thread;

        if (pthread_create(&thread, NULL, print_n(100), NULL))
        {
            printf("pthread_create error\n");
        }
    }
    return 0;
}

void *print_n(int n)
{
    printf("%d\n", n);
    return NULL;
}

This is an example program aiming to illustrate the problem. I get a segmentation fault after the second time pthread_create is called, but don't know why.

Upvotes: 2

Views: 1087

Answers (2)

Outrageous Bacon
Outrageous Bacon

Reputation: 562

The problem is that your invocation of pthread_create is not what you expect. Specifically, the third parameter print_n(100) is evaluating the result of calling the function, not passing a pointer to the function to be called by the created thread. Thus, you see "100" printed once as the function is evaluated, then its return value NULL is passed to pthread_create, which then dereferences NULL when starting the thread causing the seg fault. So it is actually the first invocation of pthread_create that is failing, not the second.

Also note that if you want to pass an argument into the function, you do so by using the 4th parameter to pthread_create. This means when you want to pass 100 to the new thread's function, you need to do so as a void* that the function print_n then needs to handle appropriately. And the function must take a void* as its argument, not some other type like int as you have.

One final thing to know: creating so many threads in a tight loop as you have exhausts thread pool resources (at least on my platform) returning the error message "Resource temporarily unavailable". You can see that by checking errno on pthread_create failure.

Here is your code I modified to take into account everything I said:

#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>

void *print_n(void*);

int main()
{
    int arg = 100;
    while (1)
    {
        pthread_t thread;

        if (pthread_create(&thread, NULL, print_n, &arg))
        {
            printf("pthread_create error: %s\n", strerror(errno));
        }
    }
    return 0;
}

void *print_n(void *n)
{
    int *arg = (int*)n;
    printf("%d\n", *arg);
    return NULL;
}

Upvotes: 2

KamilCuk
KamilCuk

Reputation: 141583

don't know why.

Because your program is calling NULL.

The function print_n(100) returns return NULL; always. So:

pthread_create(&thread, NULL, print_n(100), NULL);

is equivalent to:

print_n(100);
pthread_create(&thread, NULL, NULL, NULL);

This starts a separate thread that calls NULL. When this thread receives processor time, it dereferences NULL by calling a function there. So your program receives segmentation fault, because it's tries to read data from a protected area, dereference NULL in this case.

Funny, that there is no check if the function passed to pthread_create is NULL.

Upvotes: 0

Related Questions