Search code examples
cpthreadsfork

Child process doesn't execute function after first iteration


Program Design

My program is designed so that there are 6 child processes created. Each child process will create 3 threads. So, there should be 18 total threads.

When I create a child process, it calls a function called createThread and passes it the childIndex of that iteration (ie, 0, 1, 2, 3, 4, 5).

When the function is executed, it should:

  1. Store the child PID into the pid element in the struct childThreads.
  2. Go into a for loop and create a thread 3 times and store it's thread ID in the tid element of the same struct
  3. Print out the results just to make sure everything is working.

My issue:

When the child index is at it's first iteration (ie. 0) the output is as expected. However, at the next iteration to the last, the function stops executing halfway.

Expected output:

childThread[0].pid = 1111
childThread[0].tid[0] = 0
childThread[0].tid[1] = 1
childThread[0].tid[2] = 2

childThread[1].pid = 2222
childThread[1].tid[0] = 0
childThread[1].tid[1] = 1
childThread[1].tid[2] = 2
...
..
.

Actual Output:

childThread[0].pid = 1111
childThread[0].tid[0] = 0
childThread[0].tid[1] = 1
childThread[0].tid[2] = 2

childThread[1].pid = 2222
childThread[2].pid = 3333
childThread[3].pid = 4444
childThread[4].pid = 5555
childThread[5].pid = 6666

My Code

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/sysinfo.h>

int numChild = 6;
int numThreadsPerChild = 3;

struct childAndThreads {

    pid_t pid;
    pthread_t *tids;
};

struct childAndThreads *childThread;
pid_t *pids;

void createThreads(int i) {

    int childIndex = i;
    childThread[childIndex].pid = getpid();

    printf("childThread[%d].pid = %d\n", childIndex, childThread[childIndex].pid);

    for(int i = 0; i < numThreadsPerChild; i++) {

        childThread[childIndex].tids[i] = i;
    }

    for(int i = 0; i < numThreadsPerChild; i++) {

        printf("childThread[%d].tid[%d] = %d\n", childIndex, i, i);
    }
}

int main() {

    pids = malloc(numChild * sizeof(pid_t));

    childThread = malloc(numChild * sizeof(struct childAndThreads));
    childThread->tids = malloc(numThreadsPerChild * sizeof(pthread_t));

    for(int i = 0; i < numChild; i++) {

        switch(pids[i] = fork()) {
            case 0:
                createThreads(i);
                return 0;
            case -1:
                printf("Fork Error\n");
                break;
            default:
                //I am a parent
                break;
        }
     }

    for(int i = 0; i < numChild; i++) {
        wait(NULL);
    }
}

Solution

  • childThread->tids = malloc(numThreadsPerChild * sizeof(pthread_t));
    

    That line is not correct. It only allocates tids for the first child process. Instead it should be:

    for (int i = 0; i < numChild; i++) {
        childThread[i].tids = malloc(numThreadsPerChild * sizeof(pthread_t));
    }