gpt4 book ai didi

c - 使用 Semaphor、Mutex 和 PThread 的多线程

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:16:46 24 4
gpt4 key购买 nike

我和一个 friend 目前正在为大学编写基本的多线程示例。我们应该用多线程缓冲区来解决生产者/消费者问题。我们有一个使用互斥量和条件变量的工作版本,但是尝试使用信号量和互斥量解决这个遇到了三个主要问题。

问题 1:如果我们先启动消费者,他有时会随机消费无效字符并崩溃。

问题 2: 如果我们先启动生产者,有时他会等到消费者启动后才生产任何字符,这会导致问题 1。

问题 3:我们的生产者不会填满整个缓冲区,无论有多少生产者,在每次插入消费者消费的缓冲区后。

根据我们给定的伪代码示例,至少问题 2 和 3 不应该存在。我真的很感谢任何答案,因为我现在找不到错误。

消费者:

void *consumer_sem(void *args) {
printf("cons started\n");
char c;

while (cons_running) {
sem_wait(occupied);
pthread_mutex_lock(&mutex);

c = consume();

pthread_mutex_unlock(&mutex);
sem_post(free);

printf("consumer consumed %c\n\n", c);
sleep(2);
}
}

制作人:

void *producer1_sem(void *args) {    
printf("prod1 started\n");
char c;
int index=0;

while (prod1_running) {
c = lowercase[index];
index=next(index);

sem_wait(free);
pthread_mutex_lock(&mutex);

add(c);

pthread_mutex_unlock(&mutex);
sem_post(occupied);

printf("producer1 produced something!\n");
printf("%d elements in buffer\n\n",getElemsInBuffer());
sleep(3);
}
}

主要内容:

sem_t *occupied, *free;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int main(void) {
occupied=sem_open("/occupied", O_CREAT, 0644, 0);
free=sem_open("/free", O_CREAT, 0644, BUFFER_SIZE);

//some unrelated code called

pthread_create(&thread_ids[0], NULL, producer1_sem, NULL);
pthread_create(&thread_ids[1], NULL, producer2_sem, NULL);
pthread_create(&thread_ids[2], NULL, consumer_cond, NULL);

}

最佳答案

函数sem_open创建全局(命名)信号量,该信号量在调用 sem_unlink() 之前一直存在。

当您第二次(或进一步)运行您的程序时,sem_open 重用已经存在的信号量,并且它的值不会被重置。您可以轻松检测到:

// With O_EXCL opening already existed semaphore will fail.
occupied=sem_open("/occupied", O_CREAT | O_EXCL, 0644, 0);
if(occupied == SEM_FAILED) {
perror("Failed to create new semaphore");
exit(1);
}

实际上,当一个信号量仅被单个进程(但多个线程)使用时,用sem_init初始化它就足够了:

sem_t occupied;
//...
int main()
{
sem_init(&occupied, 0 /* do not share between processes*/, 0 /* initial value*/);
//...
}

或者,您可以在尝试创建新信号量之前销毁旧信号量:

// Destroy the semaphore if it exists.
sem_unlink("/occupied");
// Create the semaphore again.
occupied = sem_open("/occupied", O_CREAT | O_EXCL, 0644, 0);

关于c - 使用 Semaphor、Mutex 和 PThread 的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50184050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com