线程项目问题|如何从C中的多个线程等待/信号
我实际上是在做一个个人项目,我必须制作一个模拟这种行为的小程序:
有两种类型的人:村民和德鲁伊(作为Asterix/obelix)
每个村民都由ID确定(这是一个独特的数字村民)。它将在离开之前与“ nb_fights”时间打架 战场。每次战斗之前 它必须告知德鲁伊,然后等到锅重新填充锅。
德鲁伊将等待一个村民召唤。然后,它将用锅尺寸的食物重新填充锅。当NB_Refills 已经完成了,德鲁伊的成分已经用光了,它的线程必须停止。
所有内容都以参数(./ panoramix< nb_villagers>< lt; pot_size> nb_fights> nb_refills> nb_refills> gt; gt; gt; gt; gt; gt;
实际上,我实际上是我做了70%的项目,但是我做了70%的人,但我却遇到了麻烦的是druiid druil druil the potions potions。
有村民线程的代码:
void *villager(void *args)
{
int pNb = nbF;
int id = *(int *)args;
printf("Villager %d: Going into battle!\n", id);
while (pNb > 0) {
pthread_mutex_lock(&mpot);
printf("Villager %d: I need a drink... I see %d servings left.\n", id, pot_size);
if (pot_size == 0) {
printf("Villager %d: Hey Pano wake up! We need more potion.\n", id);
sem_wait(&test);
}
pot_size--;
pthread_mutex_unlock(&mpot);
pNb--;
printf("Villager %d: Take that roman scum! Only %d left.\n", id, pNb);
}
printf("Villager %d: I’m going to sleep now.\n", id);
}
使用 pnb =战斗数(我们减少),
然后有德鲁伊线程:
void *druid(void *args)
{
int sizepot = pot_size;
printf("Druid: I'm ready... but sleepy...\n");
while (nb_refills > 0) {
while (pot_size != 0) {
}
sem_wait(&test);
nb_refills--;
printf("Druid: Ah! Yes, yes, I'm awake! Working on it! Beware I can only make %d more refills after this one.\n", nb_refills);
pot_size = sizepot;
sem_post(&test);
}
printf("Druid: I'm out of viscum. I'm going back to... zZz\n");
}
我想知道我如何“调用” druid当“ pot_size”为空(= 0)。
我试图在if条件下使用信号量进行操作:(
if (pot_size == 0) {
printf("Villager %d: Hey Pano wake up! We need more potion.\n", id);
sem_wait(&test);
}
等待填充pot_size然后继续程序的druid),但我认为这不是很好。
编辑:整个代码:
#include "struct.h"
sem_t test;
pthread_mutex_t mpot;
pthread_mutex_t fill;
int nbV = 0;
int pot_size = 0;
int nbF = 0;
int nb_refills = 0;
int errorhandler(int ac, char **av)
{
if (ac != 5)
{
printf("USAGE: ./panoramix <nb_villagers> <pot_size> <nb_fights> <nb_refills> \nValues must be > 0.\n");
return (84);
}
if (atoi(av[1]) == 0 || atoi(av[2]) == 0 || atoi(av[3]) == 0 || atoi(av[4]) == 0)
{
printf("USAGE: ./panoramix <nb_villagers> <pot_size> <nb_fights> <nb_refills> \nValues must be > 0.\n");
return (84);
}
return (0);
}
void *druid(void *args)
{
int sizepot = pot_size;
printf("Druid: I'm ready... but sleepy...\n");
while (nb_refills > 0) {
while (pot_size != 0) {
usleep(1000);
}
pthread_mutex_lock(&fill);
nb_refills--;
printf("Druid: Ah! Yes, yes, I'm awake! Working on it! Beware I can only make %d more refills after this one.\n", nb_refills);
pot_size = sizepot;
pthread_mutex_unlock(&fill);
}
printf("Druid: I'm out of viscum. I'm going back to... zZz\n");
}
void *villager(void *args)
{
int pNb = nbF;
int id = *(int *)args;
printf("Villager %d: Going into battle!\n", id);
while (pNb > 0) {
pthread_mutex_lock(&mpot);
printf("Villager %d: I need a drink... I see %d servings left.\n", id, pot_size);
if (pot_size == 0) {
printf("Villager %d: Hey Pano wake up! We need more potion.\n", id);
}
pot_size--;
pthread_mutex_unlock(&mpot);
pNb--;
printf("Villager %d: Take that roman scum! Only %d left.\n", id, pNb);
}
printf("Villager %d: I’m going to sleep now.\n", id);
}
int main(int ac, char **av)
{
if (errorhandler(ac, av) == 84)
return (84);
nbV = atoi(av[1]);
pot_size = atoi(av[2]);
nbF = atoi(av[3]);
nb_refills = atoi(av[4]);
pthread_t th[nbV];
int i;
pthread_mutex_init(&mpot, NULL);
pthread_mutex_init(&fill, NULL);
sem_init(&test, 0, 1);
for (int i = 0; i < nbV; i++) {
int *a = malloc(sizeof(int));
*a = i;
if (pthread_create(&th[i], NULL, &villager, a) != 0) {
perror("Failed to create the Villager\n");
}
}
pthread_create(&th[nbV], NULL, &druid, NULL);
for (int i = 0; i < atoi(av[1]); i++) {
if (pthread_join(th[i], NULL) != 0) {
perror("Failed to launch the Villager\n");
}
}
sem_destroy(&test);
pthread_mutex_destroy(&mpot);
pthread_mutex_destroy(&fill);
return (0);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
struct
中,在一个位置访问它们变得更容易。druid()
不应调用sem_wait()
,因为这是生产者。如果所有的村民都在战斗中完成,请检查所有村庄是否在睡觉,请返回/退出。sem_wait()
上阻止Druid重新填充&amp;sem_post()
。main()
:使用
strtol()
而不是atoi()
,它为您提供了更多的控制:如何将字符串转换为c?中的整数
中的整数,如果线程没有将任何有意义的线程返回使用
pthread_join( )
。struct
, becomes easier to access them at a location.druid()
should not callsem_wait()
, as this is the producer. If all the villagers are done with fighting, check if all of them sleeping, return/exit if they're.sem_wait()
for druid to refill &sem_post()
.main()
:Use
strtol()
instead ofatoi()
, it gives you more control: How to convert a string to integer in C?You can use
pthread_detach()
if threads are not returning anything meaningful to a thread which waits for them withpthread_join()
.