Hello. I have a very simple server, in which there is a loop that looks like while( (c_sock = accept(...)) != -1) { try { boost::thread thr( boost::bind(&ServerClass::client_connection, this, c_sock)); }catch ( const std::exception & e) { std::cout << "Exception " << e << std::endl; close(c_sock); } } Now, it used to look more like while( (c_sock = accept(...)) != -1) { pthread_t thr; pthread_attr_t attrs; pthread_attr_init(&attrs); pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); thr_data * data = new thr_data(this, c_sock); pthread_create(&thr, &attrs, thread_proxy_function, thr_data); } (Actually, the pthread specific stuff and thread parameter wrapping and all that that was done with wrappers written by me. Also, there was proper error checking and all.) Now, the older version worked without any problems. However, the newer version using boost::thread ceased to work after approximately 256 threads had been created *all of which had exited*, pthread_create reporting an error Memory allocation failed which was reported as a resource allocation error by boost::thread. It seems that this problem was caused by the fact that the thread function usually got to execute and finish *before* the temporary thread object was destroyed (boost::thread destructor calls pthread_detach). Apparently LinuxThreads didn't consider it prudent to release the resources allocated to the thread upon call of pthread_detach if the thread had exited but no one had joined it yet. Is my analysis credible? Am I doing something completely idiotic here? I managed to get my server code functioning by poking at the boost::thread code and making it create threads detached by default, but that's hardly a very elegant solution. I'm testing this code in a RedHat 9 Linux box. -- Aatu Koskensilta (aatu.koskensilta@xortec.fi) "Wovon man nicht sprechen kann, daruber muss man schweigen" - Ludwig Wittgenstein, Tractatus Logico-Philosophicus
Aatu Koskensilta said:
Hello.
I have a very simple server, in which there is a loop that looks like
while( (c_sock = accept(...)) != -1) { try { boost::thread thr( boost::bind(&ServerClass::client_connection, this, c_sock)); }catch ( const std::exception & e) { std::cout << "Exception " << e << std::endl; close(c_sock); } }
Now, it used to look more like
while( (c_sock = accept(...)) != -1) { pthread_t thr; pthread_attr_t attrs; pthread_attr_init(&attrs); pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); thr_data * data = new thr_data(this, c_sock); pthread_create(&thr, &attrs, thread_proxy_function, thr_data); }
(Actually, the pthread specific stuff and thread parameter wrapping and all that that was done with wrappers written by me. Also, there was proper error checking and all.)
Now, the older version worked without any problems. However, the newer version using boost::thread ceased to work after approximately 256 threads had been created *all of which had exited*, pthread_create reporting an error Memory allocation failed which was reported as a resource allocation error by boost::thread.
It seems that this problem was caused by the fact that the thread function usually got to execute and finish *before* the temporary thread object was destroyed (boost::thread destructor calls pthread_detach). Apparently LinuxThreads didn't consider it prudent to release the resources allocated to the thread upon call of pthread_detach if the thread had exited but no one had joined it yet.
Is my analysis credible?
Sounds credible... but I didn't know the POSIX standard behaved in this manner (i.e. detaching a thread that had already ended would leak resources instead of behaving like a join in this case). I'll have to research both the standard and my own code here.
Am I doing something completely idiotic here?
No.
I managed to get my server code functioning by poking at the boost::thread code and making it create threads detached by default, but that's hardly a very elegant solution.
Agreed.
I'm testing this code in a RedHat 9 Linux box.
Do you have a short test case for this? -- William E. Kempf
William E. Kempf wrote:
Aatu Koskensilta said:
Hello.
I have a very simple server, in which there is a loop that looks like
while( (c_sock = accept(...)) != -1) { try { boost::thread thr( boost::bind(&ServerClass::client_connection, this, c_sock)); }catch ( const std::exception & e) { std::cout << "Exception " << e << std::endl; close(c_sock); } }
Now, it used to look more like
while( (c_sock = accept(...)) != -1) { pthread_t thr; pthread_attr_t attrs; pthread_attr_init(&attrs); pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); thr_data * data = new thr_data(this, c_sock); pthread_create(&thr, &attrs, thread_proxy_function, thr_data); }
(Actually, the pthread specific stuff and thread parameter wrapping and all that that was done with wrappers written by me. Also, there was proper error checking and all.)
Now, the older version worked without any problems. However, the newer version using boost::thread ceased to work after approximately 256 threads had been created *all of which had exited*, pthread_create reporting an error Memory allocation failed which was reported as a resource allocation error by boost::thread.
It seems that this problem was caused by the fact that the thread function usually got to execute and finish *before* the temporary thread object was destroyed (boost::thread destructor calls pthread_detach). Apparently LinuxThreads didn't consider it prudent to release the resources allocated to the thread upon call of pthread_detach if the thread had exited but no one had joined it yet.
Is my analysis credible?
Sounds credible... but I didn't know the POSIX standard behaved in this manner (i.e. detaching a thread that had already ended would leak resources instead of behaving like a join in this case). I'll have to research both the standard and my own code here.
Am I doing something completely idiotic here?
No.
I managed to get my server code functioning by poking at the boost::thread code and making it create threads detached by default, but that's hardly a very elegant solution.
Agreed.
I'm testing this code in a RedHat 9 Linux box.
Do you have a short test case for this?
The following program produces the strange behaviour. On my machine it
dies after 255 threads.
#include
participants (2)
-
Aatu Koskensilta
-
William E. Kempf