一些线程在大量调用时永远不会执行

Some threads never get execution when invoked in large amount

考虑以下程序,

static long count = 0;
void thread()
{
    printf("%d\n",++count);
}
int main()
{
    pthread_t t;
    sigset_t set;
    int i,limit = 30000;
    struct rlimit rlim;

    getrlimit(RLIMIT_NPROC, &rlim);
    rlim.rlim_cur = rlim.rlim_max;
    setrlimit(RLIMIT_NPROC, &rlim);

    for(i=0; i<limit; i++) {
        if(pthread_create(&t,NULL,(void *(*)(void*))thread, NULL) != 0) {
            printf("thread creation failed\n");
            return -1;
        }
    }
    sigemptyset(&set);
    sigsuspend(&set);
    return 0;
}

这个程序应该打印 1 到 30000。但它有时会打印 29945、29999、29959 等。为什么会这样?

Why this is happening?

因为您有数据竞争(未定义的行为)。

特别是这个声明:

printf("%d\n",++count);

在没有任何锁定的情况下修改全局(共享)变量。由于 ++ 不会自动递增它,因此多个线程很可能读取相同的值(比如 1234),递增它,然后将更新后的值 并行存储 ,导致 1235 被重复打印(两次或更多次),并且一个或多个增量被 lost.

一个典型的解决方案是要么使用互斥锁来避免数据竞争,要么(很少)使用原子变量(保证原子增量)。当心:原子变量很难正确。您还没有准备好使用它们。

因为 count 不是原子的,所以你在增量和后续打印中都有竞争条件。

您需要的指令是 atomic_fetch_add,以增加计数器并避免竞争条件。 cppreference 上的示例说明了您提出的确切问题。

您的示例只需稍作调整即可工作:

#include <stdio.h>
#include <signal.h>
#include <sys/resource.h>
#include <pthread.h>
#include <stdatomic.h>

static atomic_long count = 1;
void * thread(void *data)
{
    printf("%ld\n", atomic_fetch_add(&count, 1));
    return NULL;
}

int main()
{
    pthread_t t;
    sigset_t set;
    int i,limit = 30000;
    struct rlimit rlim;

    getrlimit(RLIMIT_NPROC, &rlim);
    rlim.rlim_cur = rlim.rlim_max;
    setrlimit(RLIMIT_NPROC, &rlim);

    for(i=0; i<limit; i++) {
        if(pthread_create(&t, NULL, thread, NULL) != 0) {
            printf("thread creation failed\n");
            return -1;
        }
    }
    sigemptyset(&set);
    sigsuspend(&set);
    return 0;
}

我做了一些其他更改,例如修复线程函数签名和使用正确的 printf 格式打印 long。但原子问题是为什么你没有打印出你期望的所有数字。