Pthreads的问题;改变价值等

时间:2015-03-31 22:26:41

标签: c pthreads

我知道标题含糊不清,我只是无法弄清楚还有什么可以称之为。

sleeper.h

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

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

#endif

sleeper.c

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

int rideTime(int id, int car) {

int seconds = ( rand() % 5) + 1 ;
printf ("Person %d is riding car %d for  %d seconds.\n", id, car, seconds);
sleep (seconds); 

return car;

}

void walkAroundTime(int id) {

int seconds = (rand() % 10) + 1 ;
printf ("Person %d is walking around for  %d seconds.\n", id, seconds);
sleep (seconds);

}

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被证明是无益的。

1 个答案:

答案 0 :(得分: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()代替并为每个线程创建不同的种子。