为什么 pthread_join 在 306 连接时崩溃(段错误)?
Why does pthread_join crash (seg fault) at 306 Joins?
我正在尝试创建一堆线程,请参阅了解更多有关 pthread 的信息。我复制了一个我找到的程序,它不会创建 1 个线程并加入它,而是创建 X 个线程并加入它们。
当我尝试 100 个线程(MAX_THREAD 100)时,它运行良好。所以我尝试了 1000 个线程,它崩溃了。然后是 500 个线程,它崩溃了。将它加载到 GDB 显示它在 306 个线程时崩溃。然而,这是不一致的。我可以在我正在使用的系统上将它设置为 304,有时它会崩溃,有时它不会。
我将 pthread_create 中的所有 pthread_t 保存在一个数组中,因此我不应该尝试加入同一个线程两次。
段错误发生在这里:
程序收到信号 SIGSEGV,分段错误。
pthread_join 中的 0x004e420e () 来自 /lib/libpthread.so.0
这是我正在使用的代码。
代码:
#define MAX_THREAD 306
#include <pthread.h>
#include <stdio.h>
int something_worked(void) {
/* thread operation might fail, so here's a silly example */
void *p = malloc(10);
free(p);
return p ? 1 : 0;
}
void *myThread(void *result)
{
if (something_worked()) {
*((int*)result) = 42;
pthread_exit(result);
} else {
pthread_exit(0);
}
}
int main()
{
pthread_t tid[MAX_THREAD];
void *status[MAX_THREAD] ;
int result[MAX_THREAD];
int i = 0;
for(i = 0; i < MAX_THREAD; i++)
{
pthread_create(&tid[i], NULL, myThread, &result[i]);
}
for(i = 0; i < MAX_THREAD; i++)
{
pthread_join(tid[i], &status[i]);
}
for(i = 0; i < MAX_THREAD; i++)
{
if (status[i] != 0) {
printf("Thread:[%d] TID[%02x] result %d\n",i, (unsigned)(tid[i]), result[i]);
} else {
printf("thread failed\n");
}
}
return 0;
}
我不应该 运行 没话题了:
cat /proc/sys/kernel/threads-max
7470
ulimit 似乎“不错”:
[machine~]$ ulimit -s
10240
[machine~]$ ulimit -v
unlimited
知道为什么我的 pthread_join 崩溃了吗?
I shouldn't be running out of threads:
请注意,这是一个 system-wide 限制,因此如果您有一些其他进程有很多线程 运行,您可能会 运行 线程不足。
在我的 x86_64
系统上,您的程序在 1000 个线程下运行良好。
在 32 位模式下构建时确实失败。那是因为默认的 ulimit -s
是 8MiB,每个线程都继承了这个设置。 8MiB * 307 == 2456MiB,高于 2GiB。
如果您实际上是在 32 位系统上,2GiB 可能是 user-space 进程的内存限制(这取决于您的内核配置方式)。
请注意,失败是由来自 pthread_create
的错误 return 指示的,并且您的程序 没有正确处理 这样的错误 return,这就是它崩溃的原因。
具体来说:
pthread_t tid[MAX_THREAD]; // uninitialized array of tid's
for(i = 0; i < MAX_THREAD; i++)
{
// If this call fails ...
pthread_create(&tid[i], NULL, myThread, &result[i]);
// ... then tid[i] is left as "random garbage" ...
}
for(i = 0; i < MAX_THREAD; i++)
{
// ... which is used here, resulting in the crash.
pthread_join(tid[i], &status[i]);
}
触摸'。
getconf LONG_BIT
32
所以你指出了代码中的 1 个错误,以及我的假设中的 1 个错误,两者都是正确的!
A: 代码错误没有检查 pthread_create() 的 return 值。
B: 我以为我在一台内存充足的 64 位机器上。
因此我更新了程序以检查 pthread_create() 的 return 值,并将 create/join 循环限制为最后一个“良好”创建。
#define MAX_THREAD 1000
#include <pthread.h>
#include <stdio.h>
int something_worked(void) {
/* thread operation might fail, so here's a silly example */
void *p = malloc(10);
free(p);
return p ? 1 : 0;
}
void *myThread(void *result)
{
if (something_worked()) {
*((int*)result) = 42;
pthread_exit(result);
} else {
pthread_exit(0);
}
}
int main()
{
pthread_t tid[MAX_THREAD] = { };
void *status[MAX_THREAD] = { };
int result[MAX_THREAD] = { };
int i = 0;
int ptc_rtn = 0;
int max_t = MAX_THREAD;
for(i = 0; i < MAX_THREAD; i++)
{
ptc_rtn = pthread_create(&tid[i], NULL, myThread, &result[i]);
if( ptc_rtn != 0)
{
max_t = i;
break;
}
}
for(i = 0; i < max_t; i++)
{
pthread_join(tid[i], &status[i]);
}
for(i = 0; i < max_t; i++)
{
if (status[i] != 0) {
printf("Thread:[%d] TID[%02x] result %d\n",i, (unsigned)(tid[i]), result[i]);
} else {
printf("thread failed\n");
}
}
return 0;
}
程序现在不会出现段错误,并且始终 returns 在 302 和 304 pthread_creates 之间,具体取决于当前可用的内存。
感谢您发现我的错误,并解释错误发生的原因!
我正在尝试创建一堆线程,请参阅了解更多有关 pthread 的信息。我复制了一个我找到的程序,它不会创建 1 个线程并加入它,而是创建 X 个线程并加入它们。
当我尝试 100 个线程(MAX_THREAD 100)时,它运行良好。所以我尝试了 1000 个线程,它崩溃了。然后是 500 个线程,它崩溃了。将它加载到 GDB 显示它在 306 个线程时崩溃。然而,这是不一致的。我可以在我正在使用的系统上将它设置为 304,有时它会崩溃,有时它不会。
我将 pthread_create 中的所有 pthread_t 保存在一个数组中,因此我不应该尝试加入同一个线程两次。
段错误发生在这里: 程序收到信号 SIGSEGV,分段错误。 pthread_join 中的 0x004e420e () 来自 /lib/libpthread.so.0
这是我正在使用的代码。
代码:
#define MAX_THREAD 306
#include <pthread.h>
#include <stdio.h>
int something_worked(void) {
/* thread operation might fail, so here's a silly example */
void *p = malloc(10);
free(p);
return p ? 1 : 0;
}
void *myThread(void *result)
{
if (something_worked()) {
*((int*)result) = 42;
pthread_exit(result);
} else {
pthread_exit(0);
}
}
int main()
{
pthread_t tid[MAX_THREAD];
void *status[MAX_THREAD] ;
int result[MAX_THREAD];
int i = 0;
for(i = 0; i < MAX_THREAD; i++)
{
pthread_create(&tid[i], NULL, myThread, &result[i]);
}
for(i = 0; i < MAX_THREAD; i++)
{
pthread_join(tid[i], &status[i]);
}
for(i = 0; i < MAX_THREAD; i++)
{
if (status[i] != 0) {
printf("Thread:[%d] TID[%02x] result %d\n",i, (unsigned)(tid[i]), result[i]);
} else {
printf("thread failed\n");
}
}
return 0;
}
我不应该 运行 没话题了:
cat /proc/sys/kernel/threads-max
7470
ulimit 似乎“不错”:
[machine~]$ ulimit -s
10240
[machine~]$ ulimit -v
unlimited
知道为什么我的 pthread_join 崩溃了吗?
I shouldn't be running out of threads:
请注意,这是一个 system-wide 限制,因此如果您有一些其他进程有很多线程 运行,您可能会 运行 线程不足。
在我的 x86_64
系统上,您的程序在 1000 个线程下运行良好。
在 32 位模式下构建时确实失败。那是因为默认的 ulimit -s
是 8MiB,每个线程都继承了这个设置。 8MiB * 307 == 2456MiB,高于 2GiB。
如果您实际上是在 32 位系统上,2GiB 可能是 user-space 进程的内存限制(这取决于您的内核配置方式)。
请注意,失败是由来自 pthread_create
的错误 return 指示的,并且您的程序 没有正确处理 这样的错误 return,这就是它崩溃的原因。
具体来说:
pthread_t tid[MAX_THREAD]; // uninitialized array of tid's
for(i = 0; i < MAX_THREAD; i++)
{
// If this call fails ...
pthread_create(&tid[i], NULL, myThread, &result[i]);
// ... then tid[i] is left as "random garbage" ...
}
for(i = 0; i < MAX_THREAD; i++)
{
// ... which is used here, resulting in the crash.
pthread_join(tid[i], &status[i]);
}
触摸'。
getconf LONG_BIT
32
所以你指出了代码中的 1 个错误,以及我的假设中的 1 个错误,两者都是正确的!
A: 代码错误没有检查 pthread_create() 的 return 值。
B: 我以为我在一台内存充足的 64 位机器上。
因此我更新了程序以检查 pthread_create() 的 return 值,并将 create/join 循环限制为最后一个“良好”创建。
#define MAX_THREAD 1000
#include <pthread.h>
#include <stdio.h>
int something_worked(void) {
/* thread operation might fail, so here's a silly example */
void *p = malloc(10);
free(p);
return p ? 1 : 0;
}
void *myThread(void *result)
{
if (something_worked()) {
*((int*)result) = 42;
pthread_exit(result);
} else {
pthread_exit(0);
}
}
int main()
{
pthread_t tid[MAX_THREAD] = { };
void *status[MAX_THREAD] = { };
int result[MAX_THREAD] = { };
int i = 0;
int ptc_rtn = 0;
int max_t = MAX_THREAD;
for(i = 0; i < MAX_THREAD; i++)
{
ptc_rtn = pthread_create(&tid[i], NULL, myThread, &result[i]);
if( ptc_rtn != 0)
{
max_t = i;
break;
}
}
for(i = 0; i < max_t; i++)
{
pthread_join(tid[i], &status[i]);
}
for(i = 0; i < max_t; i++)
{
if (status[i] != 0) {
printf("Thread:[%d] TID[%02x] result %d\n",i, (unsigned)(tid[i]), result[i]);
} else {
printf("thread failed\n");
}
}
return 0;
}
程序现在不会出现段错误,并且始终 returns 在 302 和 304 pthread_creates 之间,具体取决于当前可用的内存。
感谢您发现我的错误,并解释错误发生的原因!