A thread startup bug in openrtmfp/Cumulus primer (20) cumulus
- Author: Liu Da-poechant (Zhong Chao)
- Email: zhongchao. USTC # gmail.com (#-> @)
- Blog: blog.csdn.net/poechant
- Date: June 25Th, 2012
The threads in cumulus all inherit from startable, and encapsulate the POCO: thread member in it, which makes some operations on the thread more convenient. The START function in startable is as follows:
void Startable::start() { if(!_stop) // if running return; ScopedLock
lock(_mutex); if(_haveToJoin) { _thread.join(); _haveToJoin=false; } try { DEBUG("Try to start up a new thread inherited from Startable"); _thread.start(_process); _haveToJoin = true; ScopedLock
lock(_mutexStop); _stop=false; } catch (Poco::Exception& ex) { ERROR("Impossible to start the thread : %s",ex.displayText().c_str()); }}
If such a class inherits startable and passes in to itself at startup, it will call startable: Start () and then call its own run () function. In general, this function will take socketmanager as an example:
void SocketManager::run() { … while(running()) { … }}
Let's take a look at how this running () is going on, as shown below:
inline bool Startable::running() const { return !_stop;}
It is easy to use the startable: _ stop member to determine whether to continue the loop. When is this _ stop set to false? It is the above start (). One problem exists here is to start the thread first, and then set _ stop to false.
_thread.start(_process);_stop=false;
When run () after start (), it starts to judge the value of _ stop through running. So when you use Cumulus, you will find that the number of threads started is incorrect sometimes. Under normal circumstances, there should be four threads:
They are:
- Main thread
- Rtmfpserver thread
- Mainsockets thread
- Rtmfpmanager thread
The exception may be that mainsockets is not started, or even mainsockets and rtmfpmanager are not started.
If mainsockets is not started, the client cannot be connected successfully.
When both mainsockets and rtmfpmanager are not started, t.t
You can use GDB to check which thread has not been started successfully.
The solution is to set _ stop before starting the thread. Note that the lock must be moved at the same time and the _ Stop value is set to true when an exception occurs.
void Startable::start() { if(!_stop) // if running return; ScopedLock
lock(_mutex); if(_haveToJoin) { _thread.join(); _haveToJoin=false; } try { DEBUG("Try to start up a new thread inherited from Startable"); { ScopedLock
lock(_mutexStop); _stop=false; } _thread.start(_process); _haveToJoin = true; } catch (Poco::Exception& ex) { { ScopedLock
lock(_mutexStop); _stop = true; // June 25th, 2012, Michael@YY } ERROR("Impossible to start the thread : %s",ex.displayText().c_str()); }}
-
For more information, see the csdn blog blog.csdn.net/poechant from LIU Da poechant (zhongchao ).
-