【问题标题】:C - Double Free Error with PthreadsC - Pthreads 的双重释放错误
【发布时间】:2017-02-26 14:23:57
【问题描述】:

这是一些代码的精简版本,可以完美地作为单线程程序运行。我正在尝试使其成为多线程的。目标是拥有一个全局结构列表,并在循环中为列表重新分配内存,并为循环的每次迭代将其大小扩展一个结构。我收到以下错误:

Terminated due to signal: ABORT TRAP (6)
doublefree(54652,0x70000020a000) malloc: *** error for object 
0x7fbc13403400: double free

如前所述,如果线程数为 1,则它可以工作。我假设多个线程在 realloc() 期间试图释放相同的内存。但是互斥锁不应该阻止吗?列表的指针是全局的,所以不是每个线程都应该看到其他线程更改的指针吗?我看不出这与单线程版本有什么不同。如果我一遍又一遍地运行它,我最终可以得到正确的输出,所以有一些我看不到的竞争条件。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

typedef struct { 
    char key[512];
    int value; 
} KV_Pair;
KV_Pair *pairList;
int count = 0;
void *doStuff(void *args);
pthread_mutex_t mutex;

int main(int argc, char *argv[]) {
    pairList = malloc(sizeof(KV_Pair));
    pthread_t threads[4];
    int i;
    for(i = 0; i < 4; i++) {
        pthread_create(&(threads[i]), NULL, doStuff, NULL); }
    for(i = 0; i < 4; i++) {
        pthread_join(threads[i], NULL); }
    free(pairList);
}
void *doStuff(void *args) {
    while (1) {
        pthread_mutex_lock(&mutex);
        count++;
        pairList = 
            realloc(pairList, sizeof(KV_Pair) * count);
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(0);
}

【问题讨论】:

  • 编译器可能会使用一个寄存器来存储pairlist,直到函数返回。尝试将pairList 声明为volatile KV_Pair *pairList; 以强制编译器立即将新值写回内存。
  • realloc() 最终失败并将pairlist 设置为NULL 时会发生什么?
  • @KlasLindbäck - pthread_mutex_[un]lock() 包含一个内存屏障。见stackoverflow.com/questions/3208060/…stackoverflow.com/questions/24137964/…
  • @usr 我不确定发生了什么,因此这是一条评论。发布的代码似乎不应该产生双重错误。我想知道pthread_mutext_t mutex; 在技术上是否是一个未初始化的互斥体。也许pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 会改变这种行为。
  • @usr PTHREAD_MUTEX_INITIALIZER 与 0 初始化的 pthread_mutex_t 不同。使用 OP 代码 pthread_mutex_lock(&amp;mutex); 会调用未定义的行为。正确初始化互斥锁后,代码对我有用:ideone.com/wJVKCP

标签: c multithreading pthreads


【解决方案1】:

你忘了初始化你的互斥锁:

pthread_mutex_init(&mutex, NULL);

所以锁定没有发生。如果您检查了来自以下位置的返回码,您会看到这一点:

pthread_mutex_lock(&mutex);

(22,无效参数,而不是0,成功)而不是忽略它...

【讨论】:

  • 问题已解决。你是救生员。我不敢相信我忘记了我需要初始化(我什至曾经广泛使用互斥锁)!
猜你喜欢
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
相关资源
最近更新 更多