You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pthread_create参数传递异常:线程获取值与预期不符问题咨询

问题原因

核心问题是线程访问了已被销毁的局部变量内存:
createThreads函数里的pipeFd是栈上的局部变量,当pthread_create创建线程后,函数直接返回,栈上的pipeFd会被系统回收。而新线程可能在函数返回后才启动执行,此时访问&pipeFd指向的内存,拿到的是被覆盖后的无效垃圾值(这里恰好是0)。

另外补充:你的线程函数readFifo没有返回void*类型值,会触发未定义行为,建议补充return NULL;。

修复方案

以下三种方式都能解决问题,可根据业务场景选择:

方案一:使用全局变量

把pipeFd定义为全局变量,避免函数返回后内存被销毁:

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

int pipeFd; // 全局变量

void *readFifo(void *pFd)
{
    printf("get %d\n", *(int*)pFd);
    return NULL;
}

int createThreads(char *pipeName)
{
    pipeFd = 3;
    printf("begin to pass %d\n", pipeFd);
    pthread_t tid;
    if(pthread_create(&tid, NULL, readFifo, &pipeFd) < 0)
    {
        printf("create thread failed\n");
        return -1;
    }

    return 0;
}

int main(int argc, char*argv[])
{
    char *pipeName;
    pipeName = argv[1];

    if(createThreads(pipeName) < 0) {
        printf("init read threads failed\n");
        return -1;
    } 
    while(1){
        sleep(10000);
    }
    
    return 0;
}

方案二:动态分配堆内存

用malloc在堆上分配参数内存,线程执行完后手动释放:

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

void *readFifo(void *pFd)
{
    int fd = *(int*)pFd;
    printf("get %d\n", fd);
    free(pFd); // 释放堆内存
    return NULL;
}

int createThreads(char *pipeName)
{
    int *pipeFd = malloc(sizeof(int));
    if(pipeFd == NULL) {
        printf("malloc failed\n");
        return -1;
    }
    *pipeFd = 3;
    printf("begin to pass %d\n", *pipeFd);
    pthread_t tid;
    if(pthread_create(&tid, NULL, readFifo, pipeFd) < 0)
    {
        printf("create thread failed\n");
        free(pipeFd); // 创建失败也要释放内存
        return -1;
    }

    return 0;
}

int main(int argc, char*argv[])
{
    char *pipeName;
    pipeName = argv[1];

    if(createThreads(pipeName) < 0) {
        printf("init read threads failed\n");
        return -1;
    } 
    while(1){
        sleep(10000);
    }
    
    return 0;
}

方案三:等待线程执行完成再返回

如果业务允许,在createThreads中调用pthread_join等待线程执行完毕,确保局部变量在被使用期间不会销毁:

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

void *readFifo(void *pFd)
{
    printf("get %d\n", *(int*)pFd);
    return NULL;
}

int createThreads(char *pipeName)
{
    int pipeFd = 3;
    printf("begin to pass %d\n", pipeFd);
    pthread_t tid;
    if(pthread_create(&tid, NULL, readFifo, &pipeFd) < 0)
    {
        printf("create thread failed\n");
        return -1;
    }
    pthread_join(tid, NULL); // 等待线程执行完成
    return 0;
}

int main(int argc, char*argv[])
{
    char *pipeName;
    pipeName = argv[1];

    if(createThreads(pipeName) < 0) {
        printf("init read threads failed\n");
        return -1;
    } 
    while(1){
        sleep(10000);
    }
    
    return 0;
}

内容的提问来源于stack exchange,提问作者Klen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 17:23:19