Search code examples
cmultithreadingpthreadsposixsleep

Does sleep() affect pthread execution?


I am confused about this example:

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

void *thread_func() 
{ 
    sleep(1); // removing this changes the result
    printf("\n");
    return NULL;
} 

int main() 
{ 
    int i;

    for (i = 0; i < 10000; i++) 
    {
        pthread_t tid; 
        pthread_create(&tid, NULL, thread_func, NULL); 
    }  

    pthread_exit(NULL); 
    return 0; 
}

if i run this with the sleep(1), i count 2047 lines, without it 10000, as expected. What is going on here?

EDIT: Corrected number of expected lines to 10000.


Solution

  • Putting aside that the code shown tries to created 10000 threads which, if created successfully, would print 10000 lines not 3000, the core question is:

    Why are less threads printing if each thread waits 1s compared to not waiting?

    Possible reasoning:

    Each thread eats up resources. Due to this the maximum number of threads existing concurrently is limited.

    If each thread waits for 1s before ending it can be assumed that the available resources are eaten up faster then if the thread exited immediately. So if resources are exhausted the thread's creation simply fails, which the code ignores, but just tries to create the next one.

    To see what is really going on the code should log the case of failed creation like this:

    #include <stdio.h> 
    #include <unistd.h>
    #include <pthread.h> 
    #include <errno.h>
    
    void *thread_func(void) 
    { 
        sleep(1); /* Removing this probably lowers the number of failed creations. */
        printf("\n");
        return NULL;
    } 
    
    int main(void) 
    { 
        int i;
    
        for (i = 0; i < 10000; i++) 
        {
            pthread_t tid; 
            if (errno = pthread_create(&tid, NULL, thread_func, NULL))
            {
              perror("pthread_create() failed");
            }
        }  
    
        pthread_exit(NULL); 
    
        /* Never arriving here. */
        return 0; 
    }
    

    The number of lines printed by the above code is expected to be 10000 in total, with some lines being empty going to stdout, and some listing the creation failure going to stderr.