当我尝试使用pthread_create生成一个线程时,我得到了一个EAGAIN。但是,根据我所检查的内容,线程似乎已被正确终止。
在尝试使用pthread_create创建线程时,是什么决定了操作系统给EAGAIN?未封闭的套接字/文件句柄是否可能在导致此EAGAIN中起作用(即它们共享相同的资源空间)?
最后,是否有任何工具可以检查资源使用情况,或者可以用来查看当时有多少pthread对象处于活动状态的任何函数?
答案 0 :(得分:9)
好的,找到了答案。即使调用pthread_exit或pthread_cancel,父进程仍然需要调用pthread_join来释放pthread ID,然后该ID将变为可循环使用。
最后放入pthread_join(tid,NULL)就可以了。
编辑(不是waitpid,而是pthread_join)
答案 1 :(得分:4)
实际上,EAGAIN几乎总是与进程内存不足有关。这通常与为线程分配的堆栈大小有关,您可以使用pthread_attr_setstacksize()
进行调整。但是可以运行多少线程的进程限制。您可以使用RLIMIT_NPROC作为第一个参数,使用getrlimit()
查询硬限制和软限制。
这里有很多问题专门用于跟踪线程,它们的数量,它们是死还是活等等。简单地说,跟踪它们的最简单方法是通过你编码的某种机制自己做,这可以像递增和递减全局计数器(受互斥锁保护)或更复杂的东西一样简单。
打开套接字或其他文件描述符不应导致pthread_create()
失败。如果你达到描述符的最大值,那么在创建新线程之前你已经失败了,并且必须已经成功创建新线程以打开更多线程,因此无法使用EAGAIN失败。
答案 2 :(得分:1)
根据我的观察,如果其中一个父进程调用pthread_join(),并且chilled进程试图通过调用pthread_exit()或pthread_cancel()来释放线程,那么系统无法正确释放该线程。在这种情况下,如果在成功调用pthread_create()后立即调用pthread_detach(),则此问题已得到解决。快照在这里 -
err = pthread_create(&(receiveThread), NULL, &receiver, temp);
if (err != 0)
{
MyPrintf("\nCan't create thread Reason : %s\n ",(err==EAGAIN)?"EAGAUIN":(err==EINVAL)?"EINVAL":(err==EPERM)?"EPERM":"UNKNOWN");
free(temp);
}
else
{
threadnumber++;
MyPrintf("Count: %d Thread ID: %u\n",threadnumber,receiveThread);
pthread_detach(receiveThread);
}
答案 3 :(得分:0)
另一个潜在原因:我遇到了这个问题(EAGAIN
上的pthread_create
),因为我忘记在pthread_attr_init
上调用pthread_attr_t
我试图初始化我的主题用。
答案 4 :(得分:0)
“是否有任何检查资源使用的工具”问题的可能答案? 也许有用......
void printRlimit(const char *msg, int resource){
struct rlimit rlim;
getrlimit(resource, &rlim);
printf("\n%s ", msg);
printf("soft=");
if (rlim.rlim_cur == RLIM_INFINITY)
printf("infinite");
else if (rlim.rlim_cur == RLIM_SAVED_CUR)
printf("unrepresentable");
else
printf("%lld", (long long) rlim.rlim_cur);
printf(" hard=");
if (rlim.rlim_max == RLIM_INFINITY)
printf("infinite\n");
else if (rlim.rlim_max == RLIM_SAVED_MAX)
printf("unrepresentable");
else
printf("%lld\n", (long long) rlim.rlim_max);
}
int main(){
printRlimit("RLIMIT_AS", RLIMIT_STACK);
printRlimit("RLIMIT_CORE", RLIMIT_CORE);
printRlimit("RLIMIT_CPU", RLIMIT_CPU);
printRlimit("RLIMIT_DATA", RLIMIT_DATA);
printRlimit("RLIMIT_FSIZE", RLIMIT_FSIZE);
printRlimit("RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
printRlimit("RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE);
printRlimit("RLIMIT_NPROC", RLIMIT_NPROC);
printRlimit("RLIMIT_NICE", RLIMIT_NICE);
printRlimit("RLIMIT_NOFILE", RLIMIT_NOFILE);
printRlimit("RLIMIT_RSS", RLIMIT_RSS);
printRlimit("RLIMIT_RTPRIO", RLIMIT_RTPRIO);
printRlimit("RLIMIT_RTTIME", RLIMIT_RTTIME);
printRlimit("RLIMIT_SIGPENDING", RLIMIT_SIGPENDING);
printRlimit("RLIMIT_STACK", RLIMIT_STACK);
return 0;
}