![](/img/trans.png)
[英]C++ Producer Consumer Problem with condition variable + mutex + pthreads
[英]Pthreads - Producer and consumer with condition variable and mutex - join error and strange cout
我正在使用pthreads編寫多線程程序。 這個想法很簡單:
汽車和加油站都具有一定的燃料容量,汽車用完燃料后需要前往加油站。 加油站用完燃料后,加油口運行並重新加油。 一切似乎是罰款不包括我不得不使用pthread_exit
,而不是pthread_join
等待中的主要功能,有時雙線程cout
為同一輛車出現: "-----End of fuel-----"
。 我做對了嗎?
結構和一些全局變量:
#define initialFuel 100
#define loop 10
pthread_mutex_t mutex1, mutex2;
pthread_cond_t isempty;
PetrolDistributor petrolDistributor;
struct Car {
int capacity = 10;
int petrol = 5;
};
struct PetrolDistributor {
int petrol = initialFuel;
bool isEmpty = false;
};
線程數:
void * threadSupply(void *arg )
{
for(int i = 0; i<loop; i++)
{
pthread_mutex_lock(&mutex1);
while(!petrolDistributor.isEmpty)
{
pthread_cond_wait(&isempty, &mutex1); //When signal received, do below:
usleep(2000000);
petrolDistributor.petrol = initialFuel; //Refill petrol and change state
petrolDistributor.isEmpty = false;
}
pthread_mutex_unlock(&mutex1);
}
}
void * threadPetrolDriver(void *arg )
{
Car *car;
car = (Car*) arg;
for(int i = 0; i<loop; i++)
{
while(car->petrol > 0) // Car consumes petrol here
{
usleep(200000);
cout << car->petrol << endl;
car->petrol -= 1;
}
cout << "-----End of fuel-----" << "\t\t #" << i << endl;
pthread_mutex_lock(&mutex1);
if (petrolDistributor.petrol >= 30) // If distributor almost empty?
{
petrolDistributor.petrol -= car->capacity; //Substract car's capacity amount of fuel from distributor
car->petrol = car->capacity; //Fillup mentioned capacity in car
}
else
{
petrolDistributor.isEmpty = true;
pthread_cond_signal(&isempty);
}
pthread_mutex_unlock(&mutex1);
}
}
主要:
int main()
{
pthread_t car;
pthread_t supply;
Car carPetrol;
pthread_cond_init(&isempty, NULL);
pthread_mutex_init(&mutex1, NULL);
pthread_create(&car, NULL, threadPetrolDriver, (void*) (&carPetrol));
pthread_create(&supply, NULL, threadSupply, NULL);
// pthread_join(&car, NULL); //results error: invalid conversion from ‘pthread_t* {aka long unsigned int*}’ to ‘pthread_t {aka long unsigned int}’ [-fpermissive]|
// pthread_join(&supply, NULL);
pthread_exit(NULL);
return 0;
}
輸出示例:
-----End of fuel----- #0
9
(...)
2
1
-----End of fuel----- #1
-----End of fuel----- #2 //Also for loop increments
10
9
(...)
3
2
1
-----End of fuel----- #3
10
9
(...)
問題是為什么輸出看起來像這樣? 有時可以進行五次迭代,而第六次則顯示兩次消息。 加入有什么問題? 感謝您的建議。
這輛車可以多次顯示“燃料用盡”,因為如果發現petrolDistributor快要空了,它就不會等待-它再次在while循環外旋轉,而無需加油。
如果它發現petrolDistributor的燃料不足以供汽車加油,那么您應該在這里讓汽車等待條件變量。 在petrolDistributor加油之前,不應進行以下操作:
pthread_mutex_lock(&mutex1);
if (petrolDistributor.petrol < 30) // If distributor almost empty?
pthread_cond_signal(&isempty);
// wait for sufficient fuel to be available
while (petrolDistributor.petrol < car->capacity)
pthread_cond_wait(&carwaiting, &mutex1);
// refuel
petrolDistributor.petrol -= car->capacity; //Substract car's capacity amount of fuel from distributor
car->petrol = car->capacity; //Fillup mentioned capacity in car
pthread_mutex_unlock(&mutex1);
我用了一個新的變量conditiona carwaiting
這里。 請注意,不需要petrolDistributor.isEmpty
布爾值-該謂詞只是petrolDistributor.petrol < 30
。
petrolDistributor在加油站加油后需要發信號通知正在等待的汽車:
pthread_mutex_lock(&mutex1);
// Wait for petrol to drop below low-water-mark
while(petrolDistributor.petrol >= 30)
pthread_cond_wait(&isempty, &mutex1);
usleep(2000000);
petrolDistributor.petrol = initialFuel; //Refill petrol and change state
pthread_cond_broadcast(&carwaiting); // Wake up any cars waiting for fuel
pthread_mutex_unlock(&mutex1);
注意,我在這里使用了pthread_cond_broadcast()
,因為如果將其擴展為包括多輛汽車,則可能有多個汽車在等待加油。
您的pthread_join()
調用應該只是:
pthread_join(car, NULL);
pthread_join(supply, NULL);
( pthread_join()
以pthread_t
作為參數,而不是pthread_t *
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.