c - 使用clone()和printf的段错误

标签 c linux pthreads system-calls

我正在尝试尝试如何在 Linux 3.10.0-327.3.1.el7.x86_64 中为线程实现 clone()

我正在运行这段代码,偶尔会出现段错误。我知道如果我使用 CLONE_THREAD 则无法检查线程是否完成,但为什么 printf 会导致问题? Pthread 库如何处理这个问题?没有 printf 就没有段错误。

#define STACK_SIZE (1ULL<<22) //4MB

int tmp = 10;

int threadfunc(void *ptr)
{
    printf("i'm here\n");
    tmp++;
    return 0;
}

int main()
{
    char *child_stack = malloc(STACK_SIZE);
    int child_pid = clone(&threadfunc, child_stack+(STACK_SIZE)-1, CLONE_THREAD|CLONE_SIGHAND|CLONE_VM|CLONE_FS|CLONE_FILES|SIGCHLD, NULL);

    printf("my pid: %d\n", getpid());
    printf("child pid: %d\n", child_pid);
    printf("tmp is: %d\n", val);

    return 0;
}

最佳答案

printf 函数不知道它是在克隆中调用的 任务;它是围绕 glibc pthread 库设计的。

您所做的类似于使用异步信号中断 printf,然后从信号重新输入 printf

库处理这个问题的方式是,它使用clone作为更复杂的线程实现的一部分,它用线程标识“装饰”克隆的任务。此线程标识允许 printf 锁定流操作周围的互斥体。

线程标识是什么?这意味着 C 库中与线程相关的函数可以以某种方式查询“哪个线程正在调用我?”获取一个 ID,该 ID 映射到线程描述符结构。仅使用clone 函数无法设置此身份。

关于c - 使用clone()和printf的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38067026/

相关文章:

c++ - 禁用 gcc 错误参数 '<anonymous>' 包含指向未知边界数组的指针

c - 为什么这个 C 代码可以工作?未初始化的变量有时已经设置为 0

c - 如何限制子线程或子进程以限制在 C 中 fork

c - 使用 Pthread 的动态矩阵乘法

c - 创建多个具有互斥锁和不同生命周期的线程

c++ - 用于编译 C/C++ 项目的远程基于 linux 的机器的工具

c - 该程序应该将二维数组的每一列的乘积保存在另一个一维数组中

linux - Linux-Unix 中的中文/日文用户名

linux - 使用带 -L 选项的查找

linux - 使用循环读取 bash 脚本中的文件