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

如何让pthread_create在非Linux/Solaris类Unix系统可控失败以测试?

跨Unix系统触发pthread_create失败的通用测试实现

原测试程序依赖RLIMIT_NPROC触发pthread_create失败,但该资源限制在多数非Linux/Solaris系统中仅限制用户级进程总数,而非单个进程的线程数,因此无法生效。以下是适配AIX 7.1、FreeBSD 12.1、NetBSD 9.3、OpenBSD 6.8等系统的通用方案,且不会影响当前进程外的其他进程:

核心思路

  • 优先使用系统原生的线程数限制资源(如RLIMIT_THREADS),直接限制单个进程可创建的线程总数;
  • 对不支持线程数限制的系统,通过限制进程的虚拟内存或栈空间,让新线程因内存分配失败而无法创建;
  • 用条件编译适配不同Unix系统的接口差异,保证代码的可移植性。

修改后的测试代码

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <unistd.h>

static void *threadproc(void *arg)
{
    puts("fail: pthread_create succeeded");
    return arg;
}

int main(void)
{
    int ret = 0;
    struct rlimit r;

    // 尝试设置线程数限制(优先适配支持RLIMIT_THREADS的系统)
#ifdef RLIMIT_THREADS
    r.rlim_cur = 1;
    r.rlim_max = 1;
    if (setrlimit(RLIMIT_THREADS, &r) == 0) {
        goto attempt_create;
    }
    perror("warning: setrlimit(RLIMIT_THREADS) failed, falling back to stack limit");
#endif

    // fallback方案:设置极小的栈空间限制,让新线程无法分配栈内存
    // 获取系统最小栈限制,确保设置值合法
    if (getrlimit(RLIMIT_STACK, &r) == 0) {
        r.rlim_cur = (r.rlim_min > 4096) ? r.rlim_min : 4096;
        r.rlim_max = r.rlim_cur;
        if (setrlimit(RLIMIT_STACK, &r) == 0) {
            goto attempt_create;
        }
        perror("warning: setrlimit(RLIMIT_STACK) failed, falling back to vmem limit");
    }

    // 最终fallback:限制虚拟内存总量
    r.rlim_cur = 1024 * 1024; // 1MB
    r.rlim_max = 1024 * 1024;
    if (setrlimit(RLIMIT_VMEM, &r) != 0) {
        perror("error: all setrlimit attempts failed");
        return 1;
    }

attempt_create:
    pthread_t t;
    int err = pthread_create(&t, NULL, threadproc, NULL);
    if (err) {
        printf("ok: pthread_create failed (%s)\n", strerror(err));
        ret = 0;
    } else {
        err = pthread_join(t, NULL);
        if (err) {
            printf("error: pthread_join failed (%s)\n", strerror(err));
        }
        ret = 1;
    }

    return ret;
}

方案说明

  • RLIMIT_THREADS适配:FreeBSD 12+、NetBSD 9+、OpenBSD 6.6+、AIX 7.2+等系统支持该资源限制,直接将单个进程的线程数上限设为1,当前进程已有主线程,后续pthread_create必然失败;
  • 栈空间限制:对不支持线程数限制的系统(如AIX 7.1),将栈空间限制设为系统允许的最小值,新线程因无法分配足够栈内存而创建失败;
  • 虚拟内存限制:作为最后的兜底方案,限制进程的总虚拟内存,确保新线程无法分配所需内存;
  • 所有资源限制仅作用于当前测试进程,不会影响系统内其他进程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:25:21