1

When I'm creating T threads, I have the following code in the main thread.

pthread_t threads[T];
for (a=0; a<T; a++) {
    pthread_create(&(threads[a]), NULL, foo(threads, locks, transition), NULL);
}
printf("in main thread\n");

It creates the first thread, and I noticed that it immediately begins executing the first thread. foo is called for the first thread and "in main thread" gets outputed after. My actual intent was to create all T threads first (pushing the threads into a 'ready' queue) and then continue executing code in the main thread until it exits or yields. Once main exits, I want one of the T threads to execute.

In foo function:

void foo(pthread_t *threads, pthread_mutex_t **locks, double **transition) {
    printf("in foo\n");
}

In the main_thread function:

void main_thread (int *N, int *T) {
    double **transition;
    pthread_mutex_t **locks;

    transition = malloc(*N * sizeof *transition);
    locks = malloc(*N * sizeof *locks);
    for (a=0; a< *N; a++) {
        transition[a] = malloc(*N * sizeof *transition[a]);
        locks[a] = malloc(*N * sizeof *locks[a]);
    }

    // lock for each element in transition matrix
    for (a=0; a<*N; a++) {
        for (b=0; b<*N; b++) {
            if (pthread_mutex_init(&(locks[a][b]), NULL) != 0) { 
                printf("\n mutex init has failed\n"); 
            }
        }
    }

    for (a=0; a<*N; a++) {
        for (b=0; b<*N; b++) {
            transition[a][b] = 0.0;
        }
    }

    pthread_t threads[T];
    for (a=0; a<T; a++) {
        pthread_create(&(threads[a]), NULL, foo(threads, locks, transition), NULL);
    }
    printf("in main thread\n");


}

In the main function:

int main(int argc, char *argv[]) {

    int N = 4;
    int T = 2;

    pthread_t main_t;
    pthread_create(&main_t, NULL, &main_thread(&N, &T), NULL); 

    return 0;
}
jww
  • 97,681
  • 90
  • 411
  • 885
  • 1
    Welcome to SO. please **always** show us real code. Not something you made up or retyped from your mind. This code is incomplete and cannot compile. The brackets don't match. We do not know if you accidentally added `(...)` after the function name or if this is really your code. The answers very much depend on that. – Gerhardh Nov 30 '18 at 07:52
  • "Once main exits, I want one of the T threads to execute." - I might be misunderstanding your intent, but it sounds like you only ever want to execute one thread at a time. If so, why even bother with threads ? Why not just call the `main_thread` and `foo` functions consecutively in `main` ? – Sander De Dycker Nov 30 '18 at 09:12
  • Possible duplicate of [pthread execution on linux](https://stackoverflow.com/questions/4991470/pthread-execution-on-linux), [Pthread Run a thread right after it's creation](https://stackoverflow.com/q/12536649/608639), etc. – jww Aug 14 '19 at 12:54

1 Answers1

2

With foo(...) you call the function, passing the result of it to the pthread_create function. That means the function will execute before any thread is created.

You need to pass a pointer to the thread function instead:

pthread_create(&threads[a], NULL, foo, NULL);

Also note that when the main function exits, it usually leads to the whole process exiting and that will kill all threads you have started.

If you want to keep threads running after you exit the main thread then you need to use pthread_exit from the main thread, and detach the threads you create.

And to not start the threads at once, IIRC there are attributes you can set and pass to the pthread_create function (the second argument) to start the threads as suspended. You have to explicitly resume the threads though, that won't happen automatically.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    Passing a pointer instead of calling the function is correct, of course. But will it behave as the author expects? AFAIK the threads will still be started immediately and not wait for all threads to be created. – Gerhardh Nov 30 '18 at 07:50
  • I updated my code above. I wasn't clear before, but the T threads are created inside of a main thread not the main function. So I added the & in front of foo, and I now got this error: "error: cannot take the address of an rvalue of type 'void'" – sometimesnever Nov 30 '18 at 08:10
  • @sometimesnever You're ***calling*** the `main_thread` function, not passing a pointer to the it. – Some programmer dude Nov 30 '18 at 08:49
  • Oh, I see it now. So if I pass in a pointer to a function to execute when creating a thread, the function must not have any parameters? Would the best thing to do now is to move the variables in the parameter to global variables? – sometimesnever Nov 30 '18 at 09:05
  • 1
    AFAIK, there is no pthread thread attribute to start a thread suspended. Threads *always* start immediately (or when scheduled), and there is no guaranteed child-runs-first or parent-runs-first. If you want it, you need a semaphore. – EOF Nov 30 '18 at 11:26