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

使用clone创建带CLONE_THREAD标识的线程如何实现阻塞等待退出

问题根因

设置CLONE_THREAD标志后,通过clone创建的执行流会和调用方属于同一个线程组,共享同一个进程ID,内核不会将其识别为独立子进程,也不会向父进程发送退出通知,因此waitpid等所有wait族系统调用都无法捕获该执行流的退出事件,返回-1是符合设计逻辑的行为。

解决方案

因为你后续需要转汇编、不能依赖C标准库,所以可以直接通过futex + CLONE_CHILD_CLEARTID标志的组合实现无依赖的线程退出等待,无需引入额外库函数。逻辑如下:

  • 定义一个共享的整型变量作为退出标志
  • 调用clone时新增CLONE_CHILD_CLEARTID标志,同时在可选参数末尾传入该退出标志的地址,内核会自动将新线程的TID写入该地址,在线程退出时自动将地址值清0并唤醒所有等待该地址的执行流
  • 主线程通过futex系统调用阻塞等待该标志变化即可

修改后的可运行代码

#include <sys/wait.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/futex.h>
#include <sys/syscall.h>

int globalValue=0;
// 共享的线程退出标志和返回值存储
volatile int thread_exited = 0;
int thread_retval = 0;

static int childFunc(void*arg)
{
    printf("Global value is %d\n", globalValue);
    globalValue += *(int*)&arg;
    thread_retval = 31;
    return 31;
}

// 简单的futex等待封装,转汇编时直接替换为对应架构的系统调用即可
static void futex_wait(volatile int *addr, int expect)
{
    syscall(SYS_futex, addr, FUTEX_WAIT, expect, NULL, NULL, 0);
}

int main(int argc, char *argv[])
{
    auto stack_size = 1024 * 1024;
    auto stack = (char*)mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
    if (stack == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); }

    globalValue = 5;

    // 新增CLONE_CHILD_CLEARTID标志,末尾传入退出标志地址
    auto pid = clone(childFunc, stack + stack_size, CLONE_THREAD|CLONE_VM|CLONE_SIGHAND|CLONE_CHILD_CLEARTID, (void*)7, NULL, NULL, &thread_exited);
    sleep(1); //避免printf输出冲突,转汇编时可根据需求删除
    if (pid == -1) { perror("clone"); exit(EXIT_FAILURE); }
    printf("clone() returned %d\n", pid);

    // 阻塞等待线程退出,替代原waitpid调用
    futex_wait(&thread_exited, pid);

    printf("Expecting 12 got %d. Expecting 31 got %d.\n", globalValue, thread_retval);
    return 0;
}

转汇编注意事项

两种系统调用的参数非常简单,仅需传递地址、标志两个核心参数,不同架构的系统调用号可直接参考内核源码头文件:

  • x86_64架构:SYS_futex编号为202
  • arm64架构:SYS_futex编号为240
    不需要依赖任何C标准库的封装,直接按系统调用规则传参即可实现完整功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:45:04