1

Given a finite number of doctors and an infinite number of patients (which are generated at random moments (in the while(1) loop ), I need to make a program that describes the scheduling. So far, I made a linked list containing the ids of the threads that are currently under consultation at some doctor and the while(1) loop breaks when hitting CTRL + C. At this point, no more patients are generated, and the ones that haven't finished their consultation, are being waited to finish ( with pthread_join). My problem is now: how do I wait (pthread_join) those ones, only knowing their ID's from the linked list?

For processes, I have waitpid(pid), but for threads, how do I overcome this?

Below is my code if it helps


#define MAX_CONSULTATION_TIME 15
#define noOfDoctors 4

struct node
{
    struct node *next;
    pid_t pid;
}*head, *tail;

void * need_a_doctor(int *noOfPatient)
{

        arrivalTime[*noOfPatient] = time(NULL);
        if(sem_wait(&sem))
    {
        perror(NULL);
        return errno;
    }
    pid_t myPid = pthread_self();
    printf(" pid: %d " , myPid);
    struct node * n;
    n = add_a_new_patient_thread(myPid);    
    int *indexDoctor;
    indexDoctor = (int *)malloc(sizeof(int));
    block_doctor(indexDoctor);
    time_t currentTime = time(NULL);
    unsigned long long periodBlockDoctor = rand() % (MAX_CONSULTATION_TIME + 1);
    printf("Under consultation doctor %d with patient %d\n", (*indexDoctor) + 1, *noOfPatient);
    sleep(periodBlockDoctor);

    release_doctor(indexDoctor);
    printf("Patient %d with doctor %d waited for %ld seconds and the consultation took %lld seconds\n" , (*noOfPatient) , (*indexDoctor) + 1 , currentTime - arrivalTime[*noOfPatient] , periodBlockDoctor);
    remove_an_existing_patient(n);
    if(sem_post(&sem))
    {
        perror(NULL);
        return errno;
    }

    return NULL;
}
int main(int argc, char ** argv)
{
        head = (struct node *)malloc(sizeof(*head));
        tail = (struct node *)malloc(sizeof(*tail));
        srand(time(NULL));
        for(int i = 0 ; i < 4 ; i++)
            doctorTaken[i] = 0;
        if(argc < 1)
        {
            fprintf(stderr , "Invalid number of arguments\n");
            return -1;
        }


        if(pthread_mutex_init(&mtx , NULL))
        {
            perror(NULL);
            return errno;
        }
        if(sem_init(&sem , 0 , noOfDoctors))
        {
            perror(NULL);
            return errno;
        }

        unsigned long long timeWaitingPatient;

        int index;
        signal(SIGINT , handler_function);

        while(1)
        {

        timeWaitingPatient = rand() % 4;
        sleep(timeWaitingPatient);
        if(myExit == 1){ break;}
        printf("Patient no. %d\n" , k);

        int *index;
        index = (int *)malloc(3 * sizeof(int));

        if(index == NULL)
        {
            fprintf(stderr , "Lack of memory");
            return -1;
        }
        (*index) = k;
        pthread_t t;
        if(pthread_create(&t , NULL , need_a_doctor , index))
        {
            perror(NULL);
            return errno;
        }

            k++;
    }
    /*
    How do I join the remaining threads here?
    */
//  }
    return 0;
}

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Andrei Manolache
  • 766
  • 1
  • 8
  • 17
  • `pthread_self()` returns a `pthread_t`, not a `pid_t`. Calling `perror()` and returning `errno` after the `pthread_*` functions won't do what you want: they all return an error code and almost certainly leave `errno` alone. Please [use `sigaction()` and not `signal()`](https://stackoverflow.com/a/232711/132382). – pilcrow Jan 15 '20 at 16:07

1 Answers1

2

When you create a pthread with pthread_create, you pass in a pthread_t* to receive the thread ID. You can then wait for that thread to complete by calling pthread_join and passing it that thread ID.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278