【问题标题】:Fault address when malloc/free pthread_t across threadsmalloc/free pthread_t 跨线程时的故障地址
【发布时间】:2010-04-28 06:49:53
【问题描述】:

当我 malloc pthread_t 保存新创建的线程 id 并将其释放到另一个线程时发生故障地址。代码如下:

typedef struct _TaskInfo { 
    // int dummy_int;
    pthread_t tid;
} TaskInfo;

void* dummy_task(void* pArg) {
    free(pArg);
    return NULL;
}

void create_task() {
    TaskInfo *pInfo;
    pthread_attr_t attr;

    // set detached state stuff ...

    pInfo = (TaskInfo*) malloc(sizeof(TaskInfo));
    pthread_create(&pInfo->tid, &attr, dummy_task, pInfo);

    // destroy pthread attribute stuff ...
}

int main() {
    int i;
    while(i < 10000) {
        create_task();
        ++i;
    }
    return 0;
}

当我取消注释 TaskInfo 的成员 dummy_int 时,它有时会成功运行,但有时会失败。 我的平台是 VMWare + Ubuntu 9.10 + ndk r3

谢谢!

【问题讨论】:

    标签: android android-ndk


    【解决方案1】:

    pthread_create() 将创建线程的线程 ID (TID) 存储在第一个参数指向的位置,但是它在创建线程后执行此操作 (http://opengroup.org/onlinepubs/007908799/xsh/pthread_create.html):

    成功完成后,pthread_create() 将创建的线程的 ID 存储在线程引用的位置

    由于线程已经创建,它很可能有机会在pthread_create() 有机会在其中存储 TID 之前运行并删除该内存块。

    当结构中没有dummy_int 成员时,您可能会以一种提前崩溃的方式破坏堆。包含dummy_int 成员后,您碰巧在丢弃不那么敏感的东西(因此崩溃的频率降低了一些)。在任何一种情况下,您都在丢弃未分配的内存(或可能未分配 - 您有竞争条件)。

    【讨论】:

    • 非常感谢!但我仍然想知道为什么 Linux 上的相同代码运行良好。因为我从 Robert Love 的《Linux Kernel Development》中读到,内核首先运行子进程,Linux 上进程和线程的实现是一样的。 Linux上的线程调度和android有区别吗?
    • 我不能说 - 但无论哪种情况,由于您正在处理竞争条件,因此您正在处理在某些时候会失败的代码。可能在 Android 上失败更加“确定”,因为您可能正在处理单处理器设备,而在 Linux 上,您可能正在运行多进程设备,因此原始线程有机会在之前保存 TID free() 出现在新创建的线程中。或者 Linux 可能在调度程序上有足够的差异让你侥幸逃脱。但它仍然是错误 - 在某些情况下你只是没有注意到它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    相关资源
    最近更新 更多