2014-03-25 145 views
2

我试图做我的功课,但我坚持使用这些线程..创建线程时,该功能被称为:线程同步,互斥

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名工人,只有一名工人进入矿井挖掘金矿。我如何旋转我的线程,以便他们都可以从矿井中挖掘出来?

+0

嗨 - 人们通常懒得点击通过另一个链接。请将相关代码复制到您的问题中。 –

+0

好的,我会编辑我的帖子。 – user3132352

+1

@TarynEast让我笑了起来。谁在这里真的很懒惰? :) – this

回答

0

这两个矿山只有一个互斥体,所以只有一个工人可以在矿井中工作。如果每个矿山有一个互斥体,那么两个工人可以同时进入矿体(每个矿体有一个工人)。

+0

谢谢。但是我无法找到当矿井阵列是动态时如何动态创建互斥锁。 – user3132352

+0

你可以把一个矿和它的互斥体放在一个结构中 – SpadeAce

1

如果你想每矿一矿工,但你有更多的矿工比矿,那么你必须决定什么是闲置的矿工将采取行动时,所有的矿山使用。而且,如果你的每个矿都有一个互斥锁,并且每个人都试图获得第一个互斥锁,那么只有一个矿工会赢,而其他的将会阻塞。你可以使用一个尝试锁,但是当所有的矿井都满时,矿工们会忙着等待。

你可以使用一个信号量,这个信号量是用地雷数量初始化的。每个矿工在成功获得信号后都会知道有一个矿可用于他们,但他们不知道哪一个。您可以使用一个互斥体来保护所有地雷的使用状态。获得信号量后,您获取互斥锁,寻找可用的矿井,将其标记为正在使用,释放互斥锁并开始挖掘。然后,完成后重新获取互斥锁,将矿标记为可用,释放互斥锁,然后释放信号量。

最后,您可以使用条件变量和互斥量代替信号量。获取互斥体,并寻找可用的矿。如果找不到,请在condvar上封锁。如果你确实找到了一个,将其标记为正在使用中,释放该互斥体并开始挖掘。完成后,重新获取互斥锁,将地雷标记为可用,发出condvar信号并释放互斥锁。在condvar上唤醒的线程将自动重新获取互斥锁,并且应该循环并重新搜索可用的地雷。在这种情况下,它应该足以发送condvar而不是广播;虽然广播可以更安全。另外,一旦你有平行的矿工,你将不得不重新考虑全球的黄金和黄金收集。由于您的矿工将在没有持有互斥锁的情况下进行实际挖掘,因此他们无法在挖掘时更新这些全局数据。他们应该保留当地的黄金开采数量,并在互斥量重新获得后更新全球。也许黄金可以在矿工进入矿山之前被扣除,并且在离开矿山后更新黄金(两者都持有互斥体)。这也是一点点如果阅读黄金时,不持有互斥,因为它可能会改变你的下面...