所以我设法让我的程序运行但是出于某种原因,没有客户走进酒吧,除非他/她之前的客户先离开酒吧,我该如何解决? 我尝试了一个mutex_lock,但我可能错误地实现了它,这是我到目前为止从代码中得到的:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem;
pthread_mutex_t serve = PTHREAD_MUTEX_INITIALIZER;
void Bartender(int);
void EnterBar(int);
void OrderStart(int);
void ServeStart(int);
void ServeDone(int);
void OrderDone(int);
void DrinkBeer(int);
void LeaveBar(int);
void* Customer(void*);
void Bartender(int cid)
{
ServeStart(cid);
ServeDone(cid);
}
void* Customer(void* id)
{
int cid =(int)id;
EnterBar(cid);
LeaveBar(cid);
return NULL;
}
void EnterBar(int cid){
sem_wait(&sem); //decrease semaphore
printf("Customer %d enters the bar.\n", cid);
int cups;
for(cups=0;cups<(cid%3+1);cups++){
pthread_mutex_lock(&serve);
OrderStart(cid);
OrderDone(cid);
DrinkBeer(cid);
pthread_mutex_unlock(&serve);
}
}
void OrderStart(int cid)
{
printf("Customer %d asks for beer.\n", cid);
Bartender(cid);
}
void OrderDone(int cid)
{
printf("Customer %d gets the beer.\n", cid);
}
void DrinkBeer(int cid)
{
printf("Customer %d drinks the beer.\n", cid);
}
void LeaveBar(int cid)
{
printf("Customer %d leaves the bar.\n", cid);
sem_post( &sem ); //increase semaphore
}
void ServeStart(int cid)
{
printf("Bartender starts to serve customer %d.\n", cid);
}
void ServeDone(int cid)
{
printf("Bartender is done serving customer %d.\n", cid);
}
int main (int argc, char *argv[])
{
int t;
long rc;
int num_customers = atoi(argv[1]); //number of customers
int capacity = atoi(argv[2]); //bar capacity
if(num_customers > 0 && capacity > 0){
rc = sem_init( &sem, 0, capacity );
if (rc)
{
printf("ERROR; return code from sem_init() is %ld\n",rc);
exit(-1);
}
//pthread_t threads[num_customers];
pthread_t *threads = (pthread_t*)malloc(num_customers*sizeof(pthread_t));
if(random() > RAND_MAX / 2)
usleep(1);
//rc = sem_init(&sem1,0,capacity);
//rc = pthread_barrier_init(&barrier1, NULL, num_customers);
for(t=0; t<num_customers;t++){
printf("In main: creating thread %d\n", t);
//printf("CAPACITY: %d\n", capacity);
rc = pthread_create(&threads[t], NULL, Customer, (void* )t);
if (rc){
printf("ERROR; return code from pthread_create() is %ld\n", rc);
exit(-1);
}
}
for( t=0;t<num_customers;t++)
pthread_join(threads[t],NULL);
sem_destroy(&sem); //destroy semaphore
}
else{
printf("ERROR: Both parameters should be a valid positive numbers.");
exit(-1);
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
它应该允许酒吧中的多个顾客,并在完成饮用他们的啤酒后离开,而不是在顾客离开之前离开。我需要调酒师的线程吗? 有什么建议??
答案 0 :(得分:2)
#include <unistd.h>
并修改此功能
void DrinkBeer(int cid)
{
printf("Customer %d drinks the beer for 10 seconds.\n", cid);
sleep(10);
}
void LeaveBar(int cid)
{
printf("Customer %d leaves the bar (takes 10 sec).\n", cid);
sem_post( &sem ); //increase semaphore
sleep(10);
}
了解它现在的表现。你需要一些睡眠功能,因此线程可以睡眠并更好地观察其他线程的工作方式。 这种修改能否正常运作?
答案 1 :(得分:1)
我认为这是一种正确的行为,对吧? 客户2是酒吧的第一位,但客户1之后离开。
[amb@localhost ~]$ ./a.out 3 2
In main: creating thread 0
In main: creating thread 1
In main: creating thread 2
Customer 2 enters the bar.
Customer 2 asks for beer.
Bartender starts to serve customer 2.
Bartender is done serving customer 2.
Customer 2 gets the beer.
Customer 2 drinks the beer for 7 seconds.
Customer 1 enters the bar.
Customer 1 asks for beer.
Bartender starts to serve customer 1.
Bartender is done serving customer 1.
Customer 1 gets the beer.
Customer 1 drinks the beer for 8 seconds.
Customer 2 asks for beer.
Bartender starts to serve customer 2.
Bartender is done serving customer 2.
Customer 2 gets the beer.
Customer 2 drinks the beer for 6 seconds.
Customer 1 asks for beer.
Bartender starts to serve customer 1.
Bartender is done serving customer 1.
Customer 1 gets the beer.
Customer 1 drinks the beer for 4 seconds.
Customer 1 leaves the bar.
Customer 0 enters the bar.
Customer 0 asks for beer.
Bartender starts to serve customer 0.
Bartender is done serving customer 0.
Customer 0 gets the beer.
Customer 0 drinks the beer for 6 seconds.
Customer 2 asks for beer.
Bartender starts to serve customer 2.
Bartender is done serving customer 2.
Customer 2 gets the beer.
Customer 2 drinks the beer for 7 seconds.
Customer 0 leaves the bar.
Customer 2 leaves the bar.
答案 2 :(得分:1)
你不有你认为的问题。我做了以下更改。
(1) //添加全局
int count = 0;
pthread_mutex_t mutCount = PTHREAD_MUTEX_INITIALIZER;
(2)添加到酒吧的人的柜台并打印出来
void EnterBar(int cid)
{
sem_wait(&sem); //decrease semaphore
printf("Customer %d enters the bar.\n", cid);
pthread_mutex_lock(&mutCount);
count++;
printf("There are %i customers in the bar\n", count);
pthread_mutex_unlock(&mutCount);
int cups;
for (cups = 0;cups < (cid % 3 + 1);cups++)
{
pthread_mutex_lock(&serve);
OrderStart(cid);
OrderDone(cid);
DrinkBeer(cid);
pthread_mutex_unlock(&serve);
}
}
(3)当他们离开时,减少了客户的数量
void LeaveBar(int cid)
{
printf("Customer %d leaves the bar.\n", cid);
pthread_mutex_lock(&mutCount);
count--;
pthread_mutex_unlock(&mutCount);
sem_post( &sem ); //increase semaphore
}
(4)主要改变我们有意义的事情
if (random() > RAND_MAX / 2)
usleep(100);
(5)我跑了:barthread 20 15 | grep“有”
(6)我得到以下输出:
There are 1 customers in the bar
There are 2 customers in the bar
There are 1 customers in the bar
There are 3 customers in the bar
There are 4 customers in the bar
There are 5 customers in the bar
There are 6 customers in the bar
There are 7 customers in the bar
There are 6 customers in the bar
There are 6 customers in the bar
There are 5 customers in the bar
There are 5 customers in the bar
There are 5 customers in the bar
There are 6 customers in the bar
There are 4 customers in the bar
There are 4 customers in the bar
There are 5 customers in the bar
There are 6 customers in the bar
There are 7 customers in the bar
There are 8 customers in the bar
答案 3 :(得分:1)
所有这些mutex gunge有什么用?一对信号量有什么问题,一个&#39; barAccess&#39;初始化为条形容量,一个&#39; barStaff&#39;,init。调剂的数量?
#define slaughtered (beerCount==10)
{
beerCount=0;
wait(barAccess);
do{
wait(barStaff);
sleep(pouringTime);
signal(barstaff);
sleep(drinkingTime);
beerCount++;
}while(!slaughtered);
signal(barAccess);
};
如果此栏有常规客户,您可以使用&#39; sleep(soberUp)添加另一个while(true)循环;&#39;每次在布泽尔会议之后。
在开放时间内改变酒吧的数量也很容易。只需添加更多&#39; barStaff&#39;单位或偷走一些。
如果真的很忙,你可能还想打开酒吧以增加容量 - 只需要循环中的所有barAccess单元。
关闭时间应该很有趣。您需要说服客户离开,不再允许。如果他们没有在合理的时间内获得服务,也许客户应该离开。然后你就可以吸掉所有的酒吧老板,这样客户就无法获得服务并聚集在所有的barAccess单元中,这样新的客户就无法进入。最终,今天的酒吧将是空的。当你第二天打开时,首先在酒吧里推,然后barAccess单位,并观看急于获得服务!