2016-11-22 20 views
0

我在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; 
} 

編寫這些代碼,它給輸出:

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 

的問題是,如果sem_wait(&(currentCustomer->Cashiers[0]));後的第二個線程去這意味着sem_post(&(currentCustomer->Cashiers[0]));這已經發生了所以firstIsFree已經是1,爲什麼它會打印第二個printf?

+1

哪個場合想要打扮呢? ...;) – LPs

+0

@LP沒有得到這個問題,在這個領域新的,你可以問另一種方式? –

+0

好吧。這是一個笑話:[不適當](http://dictionary.cambridge.org/it/dizionario/inglese/inappropriate)。我在看你的代碼。如果我看到什麼,我會回到你身邊。 – LPs

回答

2

下面的問題出現在您的代碼中,這可能會導致未定義的行爲。請糾正它並再次嘗試執行:

在您的主函數中,您使用局部變量來獲取信號量firstsecond,並且您的主函數似乎不等待線程退出而退出。您的主要功能需要呼叫pthread_join

+0

究竟應該在哪裏調用pthread_join? –

+0

在主函數中添加一個循環,緊接在pthread_create循環之後,併爲所有創建的線程調用pthread_join。 – Jay

+0

你完全正確,但並不存在風險:這是一個具體的行爲。 – LPs