【发布时间】:2013-06-12 09:47:19
【问题描述】:
我有这个代码:
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”相同。 我还检查了 pthread_create 手册页指导的 /proc/sys/kernel/threads-max (它是 13813)。 也没有为 '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. 或者我遇到了一些我无法识别的系统限制
还想知道我的修正是否对这个问题有好处,或者我最终在这个解决方案中引入了哪些隐藏的东西、陷阱? 谢谢!
【问题讨论】:
-
不知道原来的问题是什么,我也很好奇,但是您使用的解决方案使线程使用无用。使用线程的要点是您可以并行执行任务以最大化性能,并且您正在做的是创建一个线程,而不是在创建其他线程之前等待它完成(更多关于 pthread_join:linux.die.net/人/3/pthread_join);功能上最终与调用函数相同,没有额外的好处。 (如果我说错了请有人纠正我)
-
您在数组中写入超出范围: for ( i = 1 ; i for ( i = 0 ; i
-
200 多个线程?你一定是在开玩笑吧。打电话给医生!
-
虽然我同意 200 个线程是多余的,但这可能是一个学术练习。另一方面,可能是在 Parallella、36 核 IBM system z 或能够处理 512 个线程的 16 核 SPARC 上运行的一些代码。