pthread_create和EAGAIN

时间:2011-12-26 10:07:35

标签: pthreads posix memory-leaks

当我尝试使用pthread_create生成一个线程时,我得到了一个EAGAIN。但是,根据我所检查的内容,线程似乎已被正确终止。

在尝试使用pthread_create创建线程时,是什么决定了操作系统给EAGAIN?未封闭的套接字/文件句柄是否可能在导致此EAGAIN中起作用(即它们共享相同的资源空间)?

最后,是否有任何工具可以检查资源使用情况,或者可以用来查看当时有多少pthread对象处于活动状态的任何函数?

5 个答案:

答案 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;
}