I got an EAGAIN when trying to spawn a thread using pthread_create. However, from what I've checked, the threads seem to have been terminated properly.
What determines the OS to give EAGAIN when trying to create a thread using pthread_create? Would it be possible that unclosed sockets/file handles play a part in causing this EAGAIN (i.e they share the same resource space)?
And lastly, is there any tool to check resource usage, or any functions that can be used to see how many pthread objects are active at the time?
Okay, found the answer. Even if pthread_exit or pthread_cancel is called, the parent process still need to call pthread_join to release the pthread ID, which will then become recyclable.
Putting a pthread_join(tid, NULL) in the end did the trick.
edit (was not waitpid, but rather pthread_join)
As a practical matter EAGAIN is almost always related to running out of memory for the process. Often this has to do with the stack size allocated for the thread which you can adjust with pthread_attr_setstacksize()
. But there are process limits to how many threads you can run. You can query the hard and soft limits with getrlimit()
using RLIMIT_NPROC as the first parameter.
There are quite a few questions here dedicated to keeping track of threads, their number, whether they are dead or alive, etc. Simply put, the easiest way to keep track of them is to do it yourself through some mechanism you code, which can be as simple as incrementing and decrementing a global counter (protected by a mutex) or something more elaborate.
Open sockets or other file descriptors shouldn't cause pthread_create()
to fail. If you reached the maximum for descriptors you would have already failed before creating the new thread and the new thread would have already have had to be successfully created to open more of them and thus could not have failed with EAGAIN.
As per my observation if one of the parent process calls pthread_join(), and chilled processes are trying to release the thread by calling pthread_exit() or pthread_cancel() then system is not able to release that thread properly. In that case, if pthread_detach() is call immediately after successful call of pthread_create() then this problem has been solved. A snapshot is here -
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);
}
Another potential cause: I was getting this problem (EAGAIN
on pthread_create
) because I had forgotten to call pthread_attr_init
on the pthread_attr_t
I was trying to initialize my thread with.
Possible answer to "is there any tool to check resource usage" question?
Maybe useful...
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;
}