【发布时间】:2018-09-25 14:17:39
【问题描述】:
我正在学习Linux系统编程,所以我只是尝试编写一个非常常见的程序,即生产者和消费者。我使用信号量机制来实现我的代码。不幸的是,我遇到了一个分段错误,我真的找不到我错的地方。希望有人能帮帮我,谢谢。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem_consumer;
sem_t sem_producer;
typedef struct node
{
int data;
struct node *next;
} Node;
Node * head = NULL;
void * producer(void *arg)
{
while (1)
{
sem_wait(&sem_producer);
Node *ptr = (Node *)malloc(sizeof(Node));
ptr->data = rand() % 1000;
printf("++++++ producer: %lu, %d\n", pthread_self(), ptr->data);
ptr->next = head;
head = ptr;
sem_post(&sem_consumer);
}
return NULL;
}
void * consumer(void * arg)
{
while (1)
{
sem_wait(&sem_consumer);
Node *pdel = head;
head = head -> next;
printf("------ consumer: %lu, %d\n", pthread_self(), pdel->data);
free(pdel);
sem_post(&sem_producer);
}
return NULL;
}
int main(int argc, char *argv[])
{
sem_init(&sem_consumer, 0, 0);
sem_init(&sem_producer, 0, 3);
pthread_t pthid[2];
pthread_create(&pthid[0], NULL, producer, NULL);
pthread_create(&pthid[1], NULL, consumer, NULL);
for (int i = 0; i < 2; i++)
{
pthread_join(pthid[i], NULL);
}
sem_destroy(&sem_consumer);
sem_destroy(&sem_producer);
return 0;
}
【问题讨论】:
-
在gdb中运行可能是然后bt
-
对于这些类型的错误,请使用消毒剂(在这种情况下,ThreadSanitizer)
-
另请注意,
printf()语句(例如printf("------ consumer: %lu, %d\n", pthread_self(), pdel->data);)不能保证以原子方式发出,因此如果您的代码同时运行线程,您也可能会获得交错输出。您发布的代码不应同时运行生产者和消费者线程,因此不会变得明显。 -
不是你的问题的原因,但你不应该在信号量锁内调用 printf,那将是非常低效的。而是抓取信号量,将相关部分复制到局部变量,释放信号量,打印局部变量。
-
@Lundin 你说得对,下次我会处理的。