我开始熟悉pthreads编程;以下代码是一个简单的生产者/消费者设计,其中数据从全局列表中放置/获取。问题是:消费者函数中的数据指针被尝试释放两次。此外,如果我printf()
在循环的开头添加 a ,一切似乎都很好......我做错了什么?我怀疑关键字的滥用volatile
,或者缓存隐藏的东西......除非它只是一个设计问题(可能是:p)。
感谢您的见解。
注意:malloc()/free()
在我的系统上是线程安全的。我正在使用它进行编译$ gcc -pthread -O0
,我猜这应该可以减少由于滥用volatile
. 最后,在这段代码片段中,我们并不关心内存不足(如果生产者多于消费者)。
编辑:将代码更改为单个列表头。
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
pthread_mutex_t lock;
pthread_cond_t new_data;
struct data {
int i;
struct data *next;
};
struct data *list_head = NULL;
void *consume(void *arg)
{
struct data *data;
while (1) {
pthread_mutex_lock(&lock);
while (list_head == NULL) {
pthread_cond_wait(&new_data, &lock);
}
data = list_head;
list_head = list_head->next;
pthread_mutex_unlock(&lock);
free(data);
}
return NULL;
}
void *produce(void *arg)
{
struct data *data;
while (1) {
data = malloc(sizeof(struct data));
pthread_mutex_lock(&lock);
data->next = list_head;
list_head = data;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&new_data);
}
return NULL;
}
int main()
{
pthread_t tid[2];
int i;
pthread_mutex_init(&lock, NULL);
pthread_cond_init(&new_data, NULL);
pthread_create(&tid[0], NULL, consume, NULL);
pthread_create(&tid[1], NULL, produce, NULL);
for (i = 0; i < 2; i++) {
pthread_join(tid[i], NULL);
}
}
和输出:
$ ./a.out
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x00007f5870109000 ***