2015-03-31 67 views
2

我知道標題的模糊,我只是想不出還有什麼叫它。Pthreads問題;改變價值等

sleeper.h

#ifndef SLEEPER_H 
#define SLEEPER_H 
#include <unistd.h> 

int rideTime(int, int); 
void walkAroundTime(int); 

#endif 

sleeper.c

​​

bumper_cars.c

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <time.h> 
#include "sleeper.h" 

void* person(void*); 
int getInLine(int); 
void returnCar(int); 

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t car_availability = PTHREAD_COND_INITIALIZER; 
int available_cars; 
int num_cars; 
int* cars; 

int main(int argc, char* argv[]) { 
    num_cars = atoi(argv[1]); 
    int num_people = atoi(argv[2]); 
    int sim_time = atoi(argv[3]); 

    available_cars = num_cars; 
    cars = calloc(num_cars, sizeof(int)); 
    pthread_t* threads = calloc(num_people, sizeof(pthread_t)); 

    srand((unsigned)time (NULL)); 

    for (int i = 0; i < num_cars; i++) { 
     cars[i] = 1; 
    } 

    for (int i = 0; i < num_people; i++) { 
     int* id = malloc(sizeof(*id)); 
     *id = i + 1; 
     pthread_create(&threads[i], NULL, person, (void*)(id)); 
    } 

    //printf("MAIN: Sleeping for %d seconds\n", sim_time); 
    sleep(sim_time); 
    //printf("Done sleeping.\n"); 

    for (int i = 0; i < num_people; i++) { 
     pthread_cancel(threads[i]); 
    } 

    printf("Simulation complete.\n"); 

    pthread_mutex_destroy(&lock); 
    free(cars); 
    free(threads); 

    exit(EXIT_SUCCESS); 
} 

void* person(void* arg) { 
    int car = 0; 
    int id = *((int *) arg); 
    while (1) { 
     walkAroundTime(id); 
     car = getInLine(id); 
     rideTime(id, car); 
     returnCar(car); 
    } 
} 

int getInLine(int id) { 
    int car = 0; 

    printf("Person %d is waiting for a car.\n", id); 
    pthread_mutex_lock(&lock); 

    if (available_cars == 0) { 
     pthread_cond_wait(&car_availability,&lock); 
    } 

    for (int i = 0; i < num_cars; i++) { 
     if (cars[i] == 1) { 
      car = i + 1; 
      cars[i] = 0; 
      break; 
     } 
    } 
    available_cars--; 

    return car; 
} 

void returnCar(int carID) { 
    available_cars++; 
    cars[carID] = 1; 
    printf("Car %d has been returned.\n", carID); 
    pthread_cond_broadcast(&car_availability); 
    pthread_mutex_unlock(&lock); 
} 

所以...我有兩個問題,我的計劃。最重要的是,它只適用於1輛車。如果有多輛汽車,並且其中一輛已經被佔用,所有其他人仍然必須等待它被退回。

第二個不太重要的問題是,當我用一輛車開始代碼時,汽車的id從0開始,然後在1和0之間交替,當它應該是1時。看着我的代碼,對我來說這些問題的起源並不明顯......而且gdb被證明是相當無益的。

+0

在sleeper.h中,爲什麼包含unistd.h文件?文件中的兩個原型不使用unistd.h中定義的任何項目。通常,包含在頭文件中僅適用於稍後在頭文件中使用的類型。如果在某些源文件中需要unistd.h的任何內容,那麼該源文件是包含文件應該位於的位置 – user3629249 2015-03-31 22:36:29

+0

您並未檢查* pthreads函數的任何*是否成功。如果你故意不檢查錯誤,你就沒有道德的權利去期待你的程序工作。 – 2015-03-31 22:39:33

+0

未使用參數'argc',因此編譯器會發出警告。 I.E.這段代碼不會乾淨地編譯。代碼還假定在命令行上輸入了正確的參數(和參數數量)。在獲取任何參數之前應檢查argc,以確保命令行是正確的。那麼在每次調用atoi()之後應檢查轉換後的值以確保其可用/有效 – user3629249 2015-03-31 22:40:32

回答

1

問題在於,一旦您獲取該車以獲得該車,您就會持續太久。我用這種方式修改了功能,在評論中所指出的變化:

int getInLine(int id) { 
    int car = 0; 

    printf("Person %d is waiting for a car.\n", id); 
    pthread_mutex_lock(&lock); 

    // Use a while loop because pthread_cond_wait() is subject to 
    // spurious awakenings. 
    while (available_cars == 0) { 
     pthread_cond_wait(&car_availability,&lock); 
    } 

    for (int i = 0; i < num_cars; i++) { 
     if (cars[i] == 1) { 
      car = i + 1; 
      cars[i] = 0; 
      break; 
     } 
    } 
    available_cars--; 
    // Unlock the mutex here now that we are done acquiring the car. 
    // If we don't unlock the mutex here, no one else can acquire a car. 
    pthread_mutex_unlock(&lock); 

    return car; 
} 

void returnCar(int carID) { 
    // Lock the mutex here before returning the car. 
    pthread_mutex_lock(&lock); 
    available_cars++; 
    // Need -1 here because carID is one bigger than the index. 
    cars[carID-1] = 1; 
    printf("Car %d has been returned.\n", carID); 
    pthread_cond_broadcast(&car_availability); 
    pthread_mutex_unlock(&lock); 
} 

順便說一句,我注意到您使用rand()生成隨機數。但是,如果多個線程同時調用rand(),則會得到相同的隨機數(至少這是我運行程序時發生的情況)。您應該使用rand_r(),併爲每個線程創建不同的種子。

+0

即使沒有虛假的喚醒,'while()'循環也是必要的 - 如果有多個人在等待一輛汽車,當汽車返回時它們將全部被喚醒,但其中只有一個實際上會看到'available_cars大於零 - 其餘的必須回去睡覺。 – caf 2015-03-31 23:57:31

+0

@caf好點。我在想他正在使用'pthread_cond_signal',但我看到有一個廣播。 – JS1 2015-04-01 00:02:49

+0

謝謝!我認爲這是有效的,但我不是100%肯定的,因爲數字仍然不可靠...... – Rui 2015-04-01 01:39:23