Linux C++ threads are dead, but "hanging" - thread limit
A friend of mine is trying to fix up a custom http server in C++ written for windows to work in Linux. I tried to help him, but all I found seemed too obvious.
The app creates a thread for every time a request comes in. The thread serves the request and ends. After some number of requests (something over 300) new threads are not created anymore.
All I found is that there is a limit of threads that can be created. But it looks like finished threads are still there. Is that a problem with the code or do the thread handlers never get released?
This is a bit of code my friend extracted from the app:
pthread_t threadID;
StartingArgs *arg = new StartingArgs( &(this->cameraCounts), mapToSend,&(this->mapMutex), &(this->mutex), this->config );
if( pthread_create(&threadID, NULL, (this->startingRoutine) , (void*)arg ) !开发者_JS百科= 0 )
{
ConsoleMessages::printDate();
cout<< "snapshot maker: new thread creation failed\n";
}
void *CameraCounter::startingRoutine( void *arg )
{
//stuff to do. removed for debugging
delete realArgs;
return NULL;
}
Looks like you've got a bunch of "joinable" threads. They're waiting for someone to call pthread_join() on them. If you don't want to do that (to get the return value of the thread, for example), you can create the threads as 'detached':
pthread_t threadID;
pthread_attr_t attrib;
pthread_attr_init(&attrib);
pthread_attr_setdetachstate(pthread_attr_t &attrib, PTHREAD_CREATE_DETACHED);
StartingArgs *arg = new StartingArgs( &(this->cameraCounts), mapToSend,&(this->mapMutex), &(this->mutex), this->config );
if( pthread_create(&threadID, &attrib, (this->startingRoutine) , (void*)arg ) != 0 )
{
ConsoleMessages::printDate();
cout<< "snapshot maker: new thread creation failed\n";
}
pthread_attr_destroy(&attrib);
void *CameraCounter::startingRoutine( void *arg )
{
//stuff to do. removed for debugging
delete realArgs;
return NULL;
}
You have to join the thread (pthread_join
, also see wait(2)
) after it finished or set the SIGCHILD handler to SIG_IGN.
I would recommend your friend to create a thread pool, and post work items to the thread pool. If there are available threads to service the work item, one thread is allocated, and given the work item. If no threads are available, the request should hang until a new thread is available. This way he can protect himself from draining too much system resources during a denial of service attack.
If it is unlikely that no more than 30 requests will be handled at any one time, then the thread pool should contain at the most 30 threads. The system resource allocation would then be predictable during a denial of service attack, and not depend on an arbitrary system limit.
精彩评论