pthreadsプログラミングに慣れてきました。次のコードは、データがグローバル リストから配置/フェッチされる単純なプロデューサー/コンシューマー デザインです。問題は、コンシューマー関数のデータ ポインターが 2 回解放されようとしていることです。さらに、ループの先頭にa を追加するprintf()
と、すべて問題ないように見えます...何が間違っていますか? キーワードの誤用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 ***