Giorgi Tsertsvadze
Giorgi Tsertsvadze

Reputation: 433

Threads work inappropriately

I'm writing this code in c

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

typedef struct
{
    int customerID;
    int ticketNumber;
    sem_t * freeCashiers;
    sem_t Cashiers[2];
}Customer;

int firstIsFree = 1;
int secondIsFree = 1;

void * buyTheTickets(void * data)
{
    Customer * currentCustomer = (Customer *)data;
    int ID = currentCustomer->customerID;

    currentCustomer->ticketNumber = rand()%15+1;

    sem_wait(currentCustomer->freeCashiers);    

    sem_wait(&(currentCustomer->Cashiers[0]));

    if(firstIsFree)
    {
        firstIsFree = 0;
        printf("First Cashier Sold %d Ticket To %d Customer\n",currentCustomer->ticketNumber,ID);

        usleep(1000000);
        firstIsFree = 1;

        sem_post(&(currentCustomer->Cashiers[0]));
        sem_post(currentCustomer->freeCashiers);

        return 0;
    }

    sem_post(&(currentCustomer->Cashiers[0]));

    sem_wait(&(currentCustomer->Cashiers[1]));

    if(secondIsFree)
    {
        secondIsFree = 0;
        printf("Second Cashier Sold %d Ticket To %d Customer\n",currentCustomer->ticketNumber,ID);

        usleep(1000000);
        secondIsFree = 1;

        sem_post(&(currentCustomer->Cashiers[1]));
        sem_post(currentCustomer->freeCashiers);

        return 0;
    }
    sem_post(&(currentCustomer->Cashiers[1]));
}

int main()
{
    int numberOfCustomers = 15;
    sem_t * numberOfCashiers = (sem_t*)malloc(sizeof(sem_t));
    sem_init(numberOfCashiers,0,2);
    sem_t first;
    sem_t second;
    sem_init(&first,0,1);
    sem_init(&second,0,1);

    for(int i=1;i<=numberOfCustomers;i++)
    {
        pthread_t * curTh = (pthread_t*)malloc(sizeof(pthread_t));
        Customer * curCu = (Customer *)malloc(sizeof(Customer));
        curCu->customerID = i;
        curCu->freeCashiers = numberOfCashiers;
        curCu->Cashiers[0] = first;
        curCu->Cashiers[1] = second;
        pthread_create(curTh,NULL,buyTheTickets,curCu);     
    }

    pthread_exit(0);
    return 0;
}

And it gives output:

First Cashier Sold 14 Ticket To 1 Customer

Second Cashier Sold 2 Ticket To 2 Customer

First Cashier Sold 13 Ticket To 3 Customer

Second Cashier Sold 11 Ticket To 4 Customer

First Cashier Sold 9 Ticket To 5 Customer

Second Cashier Sold 11 Ticket To 6 Customer

First Cashier Sold 2 Ticket To 7 Customer

Second Cashier Sold 13 Ticket To 8 Customer

First Cashier Sold 10 Ticket To 9 Customer

Second Cashier Sold 2 Ticket To 10 Customer

First Cashier Sold 3 Ticket To 11 Customer

Second Cashier Sold 8 Ticket To 12 Customer

First Cashier Sold 6 Ticket To 13 Customer

Second Cashier Sold 5 Ticket To 14 Customer

First Cashier Sold 9 Ticket To 15 Customer

The Question is that if the second thread goes aftersem_wait(&(currentCustomer->Cashiers[0])); It means sem_post(&(currentCustomer->Cashiers[0])); this already happened so firstIsFree is already 1 so why does it print the second printf?

Upvotes: 0

Views: 66

Answers (1)

Jay
Jay

Reputation: 24895

Below issue is present in your code which could lead to undefined behaviour. Please correct it and try the execution again:

In your main function, you are using local variables for semaphores first and second and your main function seems to exit without waiting for the threads to exit. You need to have pthread_join calls in your main function.

Upvotes: 2

Related Questions