我在努力做功课,但我被这些帖子卡住了。此函数在创建线程时调用:
size_t* mines, gold = 0, gold_collected = 0;
pthread_mutex_t mine_mutex;
int last_mine = 0;
void* dig(void *mine_start) {
int current_worker = (int)mine_start;
int mine = (int)mine_start;
// printf("Hello, it's me, thread %d\n", current_worker);
while(gold != 0) {
if(mine > last_mine - 1) {
mine = 0;
}
pthread_mutex_lock(&mine_mutex);
if(mines[mine] != 0) {
//printf("All gold %zd\n", gold);
//printf("Gold in mine %zd with number %d\n", mines[mine], mine);
printf("Worker %d entered mine %d\n", current_worker, mine);
gold -= 10;
mines[mine] -= 10;
gold_collected += 10;
//sleep(1);
}
pthread_mutex_unlock(&mine_mutex);
++mine;
}
pthread_exit(NULL);
}我的问题是,当我有5个矿和2个工人时,只有一个工人进入矿井并挖掘黄金。我如何旋转我的线程,以便所有的线程都可以从矿井中挖掘?
发布于 2014-03-25 22:55:52
如果你希望每个矿有一个矿工,但是你的矿工比矿工多,那么你必须决定当所有的矿工都在使用时,闲置的矿工会做什么。此外,如果每个矿都有一个互斥体,每个人都试图获取第一个互斥体,那么只有一个矿工会赢,其他矿工仍然会阻塞。你可以使用try锁,但是当所有的矿都满了的时候,矿工们就会忙于等待。
你可以使用一个信号量,这个信号量是用矿的数量初始化的。每个矿工,在成功获得信号量后,将知道有一个矿可供他们使用,但他们不知道是哪个矿。您可以使用一个互斥锁来保护所有地雷的使用状态。在获取信号量之后,然后获取互斥锁,寻找可用矿,将其标记为正在使用,释放互斥锁并开始挖掘。然后,完成后,重新获取互斥锁,将挖掘标记为可用,释放互斥锁,然后释放信号量。
最后,您可以使用条件变量和互斥来代替信号量。获取互斥体,并寻找可用的矿藏。如果找不到,就在condvar上阻塞。如果找到了,请将其标记为正在使用,释放互斥锁,然后开始挖掘。完成后,重新获取互斥锁,将矿标记为可用,向condvar发出信号,然后释放互斥锁。在condvar上唤醒的线程将自动重新获取互斥锁,并且应该循环并重新寻找可用的矿。在这种情况下,向condvar发送信号而不是广播就足够了;尽管广播可能更安全。
此外,一旦你有了并行的矿商,你将不得不重新考虑全球黄金和gold_collected。因为你的矿工将在没有持有互斥锁的情况下进行实际的挖掘,所以他们不能在挖掘时更新这些全局变量。他们应该保持一个他们开采的黄金数量的本地记录,并在互斥量被重新获得后更新全局。也许黄金可以在矿工进入矿场之前被扣除,而gold_collected在离开矿场后更新(两者都是在持有互斥锁的时候)。在不持有互斥量的情况下读黄金也有点可疑,因为它可能会在你下面改变……
发布于 2014-03-25 11:55:08
两个矿只有一个互斥锁,所以只有一个工人可以在矿中工作。如果每个矿有一个互斥锁,那么两个工人可以同时进入矿中(每个矿一个工人)。
https://stackoverflow.com/questions/22623552
复制相似问题