我有这段代码:
int main(int argc, char** argv)
{
pthread_t thread[thr_num];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// just for debugging //
struct rlimit rlim;
getrlimit(RLIMIT_NPROC, &rlim);
printf ("soft = %d \n", rlim.rlim_cur);
printf ("hard = %d \n", rlim.rlim_max);
////
for ( i = 1 ; i <= thr_num ; i++) {
if(pthread_create( &thread[i], &attr, loggerThread, (void*)argv ) ) {
printf("pthread_create failure, i = %d, errno = %d \n", i, errno);
exit(1);
}
}
pthread_attr_destroy(&attr);
for ( i = 1 ; i <= thr_num ; i++) {
if( pthread_join(thread[i], (void**)&status ) ) {
exit(1);
}
}
return 0;
}
void* loggerThread(void* data)
{
char** sthg = ((char**)data);
pthread_exit(NULL);
}
我不明白为什么当我用thr_num = 291运行这段代码时,我收到一个错误: pthread_create失败,i = 291,errno = 11(EAGAIN)
与thr_num = 290工作正常。我在Linux 2.6.27.54-0.2-default(SLES 11)上运行此代码 rlim.rlim_cur的值也是6906 rlim.rlim_max。我用'ulimit -a'看到'最大用户进程'。 我还检查了/ proc / sys / kernel / threads-max(它是13813),由pthread_create手册页引导。 没有为'sysctl -a'输出找到任何值为290的参数。
偶尔我从这个链接中发现: pthread_create and EAGAIN :“即使调用pthread_exit或pthread_cancel,父进程仍然需要调用pthread_join来释放pthread ID,然后它将变为可循环使用”
所以我尝试将代码修改为:
for ( i = 1 ; i <= thr_num ; i++) {
if(pthread_create( &thread[i], &attr, loggerThread, (void*)argv ) ) {
printf("pthread_create failure, i = %d, errno = %d \n", i, errno);
exit(1);
}
if( pthread_join(thread[i], (void**)&status ) ) {
printf("pthread_join failure, i = %d, errno = %d \n", i, errno);
exit(1);
}
}
pthread_attr_destroy(&attr);
然后一切正常:我没有在291周期得到错误。
我想了解为什么我的原始代码出现了错误: 1.因为线程编程错误 2.或者我达到了一些我无法识别的系统限制
还想知道我的纠正是否对这个问题有好处,或者我最终用这个解决方案引入了哪些隐藏的东西? 谢谢!
答案 0 :(得分:6)
我想了解为什么我的原始代码出现了错误:1。因为错误 使用线程进行编程2.或者我达到了一些我无法识别的系统限制
您可能达到系统限制。可能你用完了地址空间。默认情况下,每个线程在linux上获得8-10Mb的堆栈空间。如果你创建了290个线程,那么它使用了接近3Gb的地址空间 - 这是32位进程的最大值。
在这种情况下你会得到EAGAIN,因为现在没有足够的资源来创建线程(因为当时没有足够的可用地址空间)。
当一个线程退出时,并不是所有线程资源都被释放(在linux上,整个线程堆栈都被保留了)。
如果线程处于分离状态,例如你调用pthread_detach()或指定一个分离状态,当它被创建为pthread_create()的属性时,所有资源都在线程退出时释放 - 但你不能pthread_join()一个分离的线程。
< / LI>如果线程未分离,则需要在其上调用pthread_join()以释放资源。
请注意,您在循环中调用pthread_join()的修改后的代码将:
即。只有一个其他线程一次运行 - 这似乎有点无意义。
你当然可以产生多个同时运行的线程 - 但这是一个限制。在您的机器上,您似乎发现限制在290左右。
答案 1 :(得分:2)
我最初把它写成评论,但以防万一......
您的代码:
for ( i = 1 ; i <= thr_num ; i++) {
if(pthread_create( &thread[i], &attr, loggerThread, (void*)argv ) ) {
printf("pthread_create failure, i = %d, errno = %d \n", i, errno);
exit(1);
}
}
...
for ( i = 1 ; i <= thr_num ; i++) {
if( pthread_join(thread[i], (void**)&status ) ) {
exit(1);
}
}
在两个for()循环中,你从1 - thr_num检查。这意味着你的数组线程[thr_num]超出范围,因为数组从索引0开始。因此,你应该从0迭代到比thr_num少一个:
for ( i = 0 ; i < thr_num ; i++)
我真的很惊讶你在将291作为thr_num之前没有得到分段错误。