0

I am trying multithreading in my C project, using pthread. I was playing with this code but it is getting crashed and don't know why.

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

int g = 0;

void *myThreadFun(void *vargp)
{
    int *myid = (int *)vargp;
    static int s = 0;

    for(int n=0;n<1000;n++)
    {
        printf("%d\t%d\n", *myid, n); // .... line 13
    }

    printf("Thread number: %d, Static: %d, Global: %d\n", *myid, s, g);
    ++s; ++g;
}

void function()
{
    int noa=10;
    pthread_t threads[noa];
    int rc;

    for(int c=0;c<noa;c++)
    {
        rc = pthread_create(&threads[c], NULL, myThreadFun, (void *)&threads[c]);
        if (rc) {
            printf("Error:unable to create thread, %d\n", rc);
            exit(-1);
        }
        //pthread_join(threads[c], NULL); // .... line 33
    }
    pthread_exit(NULL);
}

int main()
{
    function();
}

1. If I delete line 13: printf("%d\t%d\n", *myid, n); it works properly.

I think every thread function have their own variable n and after some cycles they can access their own variable. So, why it crashed???

2. If I use line 33: pthread_join(threads[c], NULL); ,then it works but the thread works sequentially which I think perform slower.

Can someone suggest me a better approach to use faster multithreading .

Ayan Bhunia
  • 479
  • 3
  • 14
  • 1
    Could not reproduce your problem: https://repl.it/@robertwharvey/InferiorHeavyProjects#main.c – Robert Harvey Jan 24 '21 at 17:34
  • 'it works but the thread works sequentiall' well, yes, which is why you need a separate loop for the joins. – Martin James Jan 24 '21 at 17:52
  • 1
    This: 'pthread_exit(NULL);' blows away this: 'pthread_t threads[noa];' by deallocating the stack it is stored on. – Martin James Jan 24 '21 at 18:11
  • I assume that the unmanaged accesses to global and static vars was intentional, to demonstrate the effects of such? – Martin James Jan 24 '21 at 18:13
  • Your program attempts to access a `pthread_t` via an lvalue of type `int` (that is, `*myid`). That's an invitation to undefined behavior as a result of violating the strict aliasing rule. I say only an "invitation" because there are some ways that `pthread_t` could be defined that would make the access OK. There are certainly others that would make it *not* ok. – John Bollinger Jan 24 '21 at 18:19
  • Additionally, you definitely have UB on account of a data race involving `function`'s `threads[c]`, regardless of the details of type `pthread_t`. Writes that are ordered *before* the `pthread_create()` call are ordered before the actions of the created thread, but that is not true of the actions of `pthread_create()` itself. – John Bollinger Jan 24 '21 at 18:24
  • @RobertHarvey I don't know why but it is only crashes when I run it in machine (Codeblocks). But it works fine in all online gcc and clang ide. Maybe there is having some difference between how jit and offline compilation handles thread. I dont know. – Ayan Bhunia Jan 24 '21 at 20:19
  • Which compiler are you using in CodeBlocks? – Robert Harvey Jan 24 '21 at 20:19
  • @RobertHarvey GNU GCC 8.3.0 – Ayan Bhunia Jan 24 '21 at 20:25
  • How does it crash? In which line does it crash? Did you run it in a debugger? – the busybee Jan 25 '21 at 11:53

1 Answers1

0

When your main() exits, the other threads are still running and using live variables (*thr == &threads[c]) from main()s stack frame. The operation of those references is highly dependent upon your runtime and arbitrary timing. So first up:

 for(int c=0;c<noa;c++)
    {
        rc = pthread_create(&threads[c], NULL, myThreadFun, (void *)&threads[c]);
        if (rc) {
            printf("Error:unable to create thread, %d\n", rc);
            exit(1);
        }
    }
 for(int c=0;c<noa;c++)
        {
            rc = pthread_join(threads[c], NULL);
            if (rc) {
                printf("Error:unable to join thread %d, %d\n", c, rc);
                exit(1);
            }
        }

Now your threads all run in parallel, and only when they have all completed, will main exit, thus the thread array will remain live until all references to it are dead.

mevets
  • 10,070
  • 1
  • 21
  • 33