multithreadingsegmentation-faultpthreadspthread-join

Why does pthread_join crash (seg fault) at 306 Joins?


I'm playing around with creating a BUNCH of threads, just see learn a bit more about pthread. I've copied a program I found, and instead of making 1 thread, and joining it, it will create X threads, and join them.

When I tried 100 threads (MAX_THREAD 100), it worked fine. So I tried 1000 threads, and it crashed. Then 500 threads, and it crashed. Loading it into GDB showed it crashed at 306 threads. However, it's inconsistent. I can set it to 304 on the system I'm using, and sometimes it'll crash, sometimes it wont.

I'm keeping all the pthread_t's from the pthread_create in an array, so I shouldn't be trying to join the same thread twice.

The segfault happens here: Program received signal SIGSEGV, Segmentation fault. 0x004e420e in pthread_join () from /lib/libpthread.so.0

Here's the code I'm using.

Code:

#define MAX_THREAD 306

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

int something_worked(void) {
    /* thread operation might fail, so here's a silly example */
    void *p = malloc(10);
    free(p);
    return p ? 1 : 0;
}

void *myThread(void *result)
{
   if (something_worked()) {
       *((int*)result) = 42;
       pthread_exit(result);
   } else {
       pthread_exit(0);
   }
}

int main()
{
   pthread_t tid[MAX_THREAD];
   void *status[MAX_THREAD] ;
   int result[MAX_THREAD];
   int i = 0;
   
    for(i = 0; i < MAX_THREAD; i++)
    {
        pthread_create(&tid[i], NULL, myThread, &result[i]);
    }
    for(i = 0; i < MAX_THREAD; i++)
    {
        pthread_join(tid[i], &status[i]);
    }
    
    for(i = 0; i < MAX_THREAD; i++)
    {
        if (status[i] != 0) {
            printf("Thread:[%d] TID[%02x] result %d\n",i, (unsigned)(tid[i]), result[i]);
        } else {
            printf("thread failed\n");
        }
    }

   return 0;
}

I shouldn't be running out of threads:

cat /proc/sys/kernel/threads-max
7470

ulimit's seem to be "good":

[machine~]$ ulimit -s
10240
[machine~]$ ulimit -v
unlimited

Any idea why my pthread_join crashes?


Solution

  • I shouldn't be running out of threads:

    Note that this is a system-wide limit, so you could be running out of threads IF you have some other processes with many threads running.

    On my x86_64 system your program runs fine with with 1000 threads.

    It does fail when built in 32-bit mode. That is because the default ulimit -s is 8MiB, and each thread inherits that setting. 8MiB * 307 == 2456MiB, which is above 2GiB.

    If you are in fact on a 32-bit system, 2GiB might be the memory limit for user-space processes (this depends on how your kernel was configured).

    Note that the failure is signaled by error return from pthread_create, and your program does not handle such error return correctly, which is why it crashes.

    Specifically:

    pthread_t tid[MAX_THREAD];  // uninitialized array of tid's
       
    for(i = 0; i < MAX_THREAD; i++)
    {
        // If this call fails ...
        pthread_create(&tid[i], NULL, myThread, &result[i]);
        // ... then tid[i] is left as "random garbage" ...
    }
    for(i = 0; i < MAX_THREAD; i++)
    {
        // ... which is used here, resulting in the crash.
        pthread_join(tid[i], &status[i]);
    }