Hello everyone, I'm currently attempting to create a thread within a thread, and for some reason, the constructor seems to block and things just don't work very well. Consider a class ``BackupHandler'' and a class ``BackupHandlerThread'' - the thread is created for once in the 50ms polling to an output file which might be used by other processes. Now, in BackupHandler, I do this: --- boost::thread thread ( BackupHandlerThread (this->backupFile, this->data) ); --- Which, as far as I am aware of, should first create a BackupHandlerThread object, and then "launch" the thread with this object. Now, since I print out some debug info, it seems like it reaches the BackupHandlerThread constructor once, and the destructor twice. The function BackupHandlerThread::operator() () never is reached even once, and the execution of the initial thread blocks at the creation. Also, according to gdb there is no new thread being created, and it adds any use, this is the stacktrace of the thread that should create the new thread: --- [Switching to thread 3 (Thread 16386 (LWP 24085))]#0 0x401d2b94 in __pthread_sigsuspend () from /lib/i686/libpthread.so.0 (gdb) bt #0 0x401d2b94 in __pthread_sigsuspend () from /lib/i686/libpthread.so.0 #1 0x401d29d8 in __pthread_wait_for_restart_signal () from /lib/i686/libpthread.so.0 #2 0x401d2151 in pthread_create@@GLIBC_2.1 () from /lib/i686/libpthread.so.0 #3 0x400a5fc6 in boost::thread::thread(boost::function0<void, std::allocator<boost::function_base> > const&) () from /usr/local/lib/libboost_thread-gcc-mt-1_31.so.1.31.0 #4 0x080846c2 in BackupHandler::addData(std::string) (this=0x40bd2cfc, data= {static npos = 4294967295, _M_dataplus = {<allocator<char>> = {<No data fields>}, _M_p = 0x8084f10 "U\211�\203�\030�D$\f"}, static _S_empty_rep_storage = {0, 0, 0, 0}}) at function_template.hpp:427 #5 0x0808455d in BackupHandler::addData(std::string*) (this=0xfffffffc, data=0xfffffffc) at BackupHandler.cc:36 #6 0x0805a759 in Normaliser::normalise() (this=0x80bd0d8) at Normaliser.cc:81 #7 0x08079c9d in HandleClient::operator()() (this=0x80b9d38) at HandleClient.cc:37 #8 0x08052c81 in boost::detail::function::void_function_obj_invoker0<HandleClient, void>::invoke(boost::detail::function::any_pointer) (function_obj_ptr= {obj_ptr = 0xfffffffc, const_obj_ptr = 0xfffffffc, func_ptr = 0xfffffffc, data = "�"}) at function_template.hpp:128 #9 0x400a69f4 in boost::thread_group::join_all() () from /usr/local/lib/libboost_thread-gcc-mt-1_31.so.1.31.0 #10 0x401cff60 in pthread_start_thread () from /lib/i686/libpthread.so.0 #11 0x401d00fe in pthread_start_thread_event () from /lib/i686/libpthread.so.0 #12 0x402f7327 in clone () from /lib/i686/libc.so.6 (gdb) --- Thanks in advance for any ideas! Regards, Leon Mergen
Leon Mergen wrote:
Hello everyone,
I'm currently attempting to create a thread within a thread, and for some reason, the constructor seems to block and things just don't work very well.
Consider a class ``BackupHandler'' and a class ``BackupHandlerThread'' - the thread is created for once in the 50ms polling to an output file which might be used by other processes. Now, in BackupHandler, I do this:
--- boost::thread thread ( BackupHandlerThread (this->backupFile, this->data) ); ---
Which, as far as I am aware of, should first create a BackupHandlerThread object, and then "launch" the thread with this object. Now, since I print out some debug info, it seems like it reaches the BackupHandlerThread constructor once, and the destructor twice. <snip>
This calls the constructor you expected once, and then the copy constructor as well. If you don't want the BackupHandlerThread to be copied, I think you need to construct it other than as a temporary and pass a reference wrapper (boost::ref<BackupHandlerThread>) to the thread constructor. Ben.
On Mon, Dec 13, 2004 at 07:52:44PM +0000, Ben Hutchings wrote:
This calls the constructor you expected once, and then the copy constructor as well. If you don't want the BackupHandlerThread to be copied, I think you need to construct it other than as a temporary and pass a reference wrapper (boost::ref<BackupHandlerThread>) to the thread constructor.
Ahhh, this solution indeed works - thanks a lot for your quick response! Regards, Leon Mergen
Leon Mergen wrote:
On Mon, Dec 13, 2004 at 07:52:44PM +0000, Ben Hutchings wrote:
This calls the constructor you expected once, and then the copy constructor as well. If you don't want the BackupHandlerThread to be copied, I think you need to construct it other than as a temporary and pass a reference wrapper (boost::ref<BackupHandlerThread>) to the thread constructor.
Ahhh, this solution indeed works - thanks a lot for your quick response!
Remember that if you define a class that shouldn't be copiable you can easily prevent it and avoid such mishaps by deriving privately from boost::noncopiable. If you're in a situation where you can't use Boost then declare the copy constructor and copy assignment operator as private and don't define them. (See items 11 and 27 of Effective C++ or item 53 of C++ Coding Standards.) Ben.
participants (2)
-
Ben Hutchings
-
Leon Mergen