【发布时间】:2017-05-06 22:01:55
【问题描述】:
我一直在尝试通过这个简单的售票程序来学习信号量。唯一的问题是当前的信号量没有保护numTickets 和ticketsSold 的值。我发现这是因为有时售出的总票数加起来是 51。
信号量的实现是否正确?
#include <semaphore.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
int numTickets;
sem_t mySem;
void* sell_ticket(void *sellerNum) {
int sell = (int) sellerNum;
int ticketsSold = 0;
while (numTickets > 0) {
srand ( time(NULL) );
int random_number = rand();
for (int i = 1; i < random_number % 5 ; i++) {
if (numTickets > 0) {
sem_wait(&mySem);
numTickets--;
ticketsSold++;
printf("Seller # %d sold a ticket. Tickets left: %d\n", sell, numTickets);
sem_post(&mySem);
}
}
}
printf("Seller #%d noticed all tickets sold! (I sold %d myself) \n", sell, ticketsSold);
}
int main() {
numTickets = 50;
int numSellers = 4;
sem_init(&mySem, 0, 1);
pthread_t sellerThread;
for (int i = 0; i < numSellers; i++) {
pthread_create(&sellerThread, NULL, sell_ticket, (void *)i);
}
for (int i = 0; i < numSellers; i++) {
pthread_join(sellerThread, NULL);
}
printf("All tickets sold!\n");
return 0;
}
【问题讨论】:
-
我不是 pthreads 专家,但希望在另一个线程正在写入时读取 numTickets(在
if和while中)是问题所在。您需要在受信号量保护的块中获取读-修改-写序列。 -
我已经尝试了上述建议。可悲的是,经过各种测试,我得到了 51 的值。