I think I am making a simple mistake, but since I noticed there are many boost experts here, I thought I would ask for help.
I am trying to use boost threads(1_40) on windows xp. The main program loads a dll, starts the thread like so (note this is not in a class, the static does not mean static to a class but private to the file).
static boost::thread network_thread;
static bool quit = false;
HANDLE quitEvent;
//some code omitted for clarity, ask if you think it would help
void network_start()
{
HANDLE *waitHandles = (HANDLE*)malloc(3 * sizeof(HANDLE));
waitHandles[0] = quitEvent;
waitHandles[1] = recvEvent;
waitHandles[2] = pendingEvent;
do {
//read network stuff, or quit event
dwEvents =WaitForMultipleObjects(3, waitHandles, FALSE, timeout);
} while (!quit)
}
DllClass::InitInstance()
{
}
DllClass::ExportedFunction()
{
network_thread = boost::thread(boost::bind<void>(network_start));
}
DllClass::ExitInstance()
{
//signal quit (which works)
quit = true;
SetEvent(QuitEvent);
//the following code is slightly verbose because I'm trying to figure out what's wrong
try {
if (network_thread.joinable() ) {
network_thread.join();
} else {
TRACE("Too late!");
}
} catch (boost::thread_interrupted&) {
TRACE("NET INTERRUPTED");
}
}
The problem is that the main thread is hanging on the join, and the network thread is hanging at the end of _endthreadex. What am I misunderstanding?
You are not supposed to create/end threads in InitInstance/ExitInstance,
see http://support.microsoft.com/default.aspx?scid=kb;EN-US;142243 for more info. Also, see http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx about DllMain in general.
Related
I need to be able to stop a single worker thread from continuing to execute from arbitrary points in arbitrary other threads, including, but not limited to, the main thread. I had produced what I thought was working code last year, but investigations to-day following some thread deadlocks showed that it does not seem to work properly, especially as regards mutexes.
The code needs to run a particular method, path_explorer_t::step(), in a worker thread exactly once for every time that a helper method, start_path_explorer() is called in the main thread. start_path_explorer() is only ever called from the main thread.
Another method, stop_path_explorer() must be able to be called at any time by any thread (other than the thread that runs path_explorer_t::step()), and must not return until it is certain that path_explorer_t::step() has fully completed.
Additionally, path_explorer_t::step() must not be called if karte_t::world->is_terminating_threads() is true, but must instead terminate the thread at the next opportunity. The thread must not terminate in other circumstances.
The code that I have written to do this is as follows:
void* path_explorer_threaded(void* args)
{
karte_t* world = (karte_t*)args;
path_explorer_t::allow_path_explorer_on_this_thread = true;
karte_t::path_explorer_step_progress = 2;
do
{
simthread_barrier_wait(&start_path_explorer_barrier);
karte_t::path_explorer_step_progress = 0;
simthread_barrier_wait(&start_path_explorer_barrier);
pthread_mutex_lock(&path_explorer_mutex);
if (karte_t::world->is_terminating_threads())
{
karte_t::path_explorer_step_progress = 2;
pthread_mutex_unlock(&path_explorer_mutex);
break;
}
path_explorer_t::step();
karte_t::path_explorer_step_progress = 1;
pthread_cond_signal(&path_explorer_conditional_end);
karte_t::path_explorer_step_progress = 2;
pthread_mutex_unlock(&path_explorer_mutex);
} while (!karte_t::world->is_terminating_threads());
karte_t::path_explorer_step_progress = -1;
pthread_exit(NULL);
return args;
}
void karte_t::stop_path_explorer()
{
#ifdef MULTI_THREAD_PATH_EXPLORER
pthread_mutex_lock(&path_explorer_mutex);
if (path_explorer_step_progress = 0)
{
pthread_cond_wait(&path_explorer_conditional_end, &path_explorer_mutex);
}
pthread_mutex_unlock(&path_explorer_mutex);
#endif
}
void karte_t::start_path_explorer()
{
#ifdef MULTI_THREAD_PATH_EXPLORER
if (path_explorer_step_progress == -1)
{
// The threaded path explorer has been terminated, so do not wait
// or else we will get a thread deadlock.
return;
}
pthread_mutex_lock(&path_explorer_mutex);
if (path_explorer_step_progress > 0)
{
simthread_barrier_wait(&start_path_explorer_barrier);
}
if(path_explorer_step_progress > -1)
{
simthread_barrier_wait(&start_path_explorer_barrier);
}
pthread_mutex_unlock(&path_explorer_mutex);
#endif
}
However, I find that, for reasons that I do not understand, the mutex lock in stop_path_explorer() does not work properly, and it does not prevent the mutex lock line from being passed in path_explorer_threaded, with the consequence that it is possible for the thread calling stop_path_explorer() to be waiting at the cond_wait and the worker thread itself to be waiting at the top barrier underneath "do". It also seems to be able to produce conditions in which the mutex can be unlocked twice, which gives rise to undefined behaviour unless I set it to recursive.
Do I just need to set the mutex attribute to recursive and add an extra unlock inside the conditional statement in stop_path_explorer(), or is a more fundamental redesign needed? If the latter, has anyone any suggestions as to how to go about it?
Thank you in advance for any help.
Having investigated this further, I think that I have a potential answer to my own question.
I had misunderstood how pthread_cond_wait() works in conjunction with the mutex - the documentation says that it locks, not unlocks the mutex passed to it.
This means that the mutex was getting double locked from the same thread, which created undefined behaviour, and may well have resulted in some of the odd problems that I was seeing.
I have now rewritten the code as follows with a second mutex (new definitions not shown in the code sample):
void* path_explorer_threaded(void* args)
{
karte_t* world = (karte_t*)args;
path_explorer_t::allow_path_explorer_on_this_thread = true;
karte_t::path_explorer_step_progress = 2;
int mutex_error = 0;
do
{
simthread_barrier_wait(&start_path_explorer_barrier);
karte_t::path_explorer_step_progress = 0;
simthread_barrier_wait(&start_path_explorer_barrier);
if (karte_t::world->is_terminating_threads())
{
karte_t::path_explorer_step_progress = 2;
break;
}
path_explorer_t::step();
mutex_error = pthread_mutex_lock(&path_explorer_mutex);
karte_t::path_explorer_step_progress = 1;
mutex_error = pthread_mutex_unlock(&path_explorer_mutex);
pthread_cond_signal(&path_explorer_conditional_end);
mutex_error = pthread_mutex_lock(&path_explorer_mutex);
karte_t::path_explorer_step_progress = 2;
mutex_error = pthread_mutex_unlock(&path_explorer_mutex);
} while (!karte_t::world->is_terminating_threads());
karte_t::path_explorer_step_progress = -1;
pthread_exit(NULL);
return args;
}
void karte_t::stop_path_explorer()
{
#ifdef MULTI_THREAD_PATH_EXPLORER
int mutex_error = 0;
while (path_explorer_step_progress == 0)
{
mutex_error = pthread_mutex_lock(&path_explorer_mutex);
pthread_cond_wait(&path_explorer_conditional_end, &path_explorer_cond_mutex);
if (&path_explorer_mutex)
{
mutex_error = pthread_mutex_unlock(&path_explorer_mutex);
mutex_error = pthread_mutex_unlock(&path_explorer_cond_mutex);
}
}
#endif
}
void karte_t::start_path_explorer()
{
#ifdef MULTI_THREAD_PATH_EXPLORER
if (path_explorer_step_progress == -1)
{
// The threaded path explorer has been terminated, so do not wait
// or else we will get a thread deadlock.
return;
}
if (path_explorer_step_progress > 0)
{
simthread_barrier_wait(&start_path_explorer_barrier);
}
if(path_explorer_step_progress > -1)
{
simthread_barrier_wait(&start_path_explorer_barrier);
}
#endif
}
However, I do not believe that this code is working fully correctly. The software from which this is taken, an open source computer game, is designed to be playable over the internet in a multi-player configuration using lockstep networking (meaning that the server and client must execute the code from the defined start point exactly deterministically or they will get out of sync). When using this code, the clients will eventually go out of sync with the server, whereas they would not with the original code (provided, that is, that server and client were running identical executables: I was having trouble with client and server going out of sync when the executables were differently compiled, e.g. GCC and Visual Studio, and I suspect that the undefined behaviour might be the culprit there).
If anyone can confirm whether my new code is correct or has any noticeable flaws, I should be very grateful.
I write my professional application and I have one problem with the serial port thread.
I have cpu consuption. When I add SerialCtrl.h (from project SerialCtrl http://www.codeproject.com/Articles/99375/CSerialIO-A-Useful-and-Simple-Serial-Communication ) in my project my CPU % is become more 100% so without is near 40%.
I use VS C++ 2012 Professional in ANSI 32 bits MFC MT
SerialCtrl.cpp
const unsigned short MAX_MESSAGE = 300;
IMPLEMENT_DYNCREATE(SerialThread,CWinThread)
SerialThread::SerialThread() :m_serialIO(NULL)
{
}
SerialThread::~SerialThread()
{
m_serialIO = NULL;
}
BOOL SerialThread::InitInstance()
{
return TRUE;
}
int SerialThread::Run()
{
// Check signal controlling and status to open serial communication.
while(1)
{
while(m_serialIO->GetProcessActivateValue()==TRUE)
{
if ((serialCtrl().GetPortStatus()==FALSE)&&m_serialIO->GetPortActivateValue()==TRUE)
{
if(serialCtrl().OpenPort(m_serialIO->m_DCB,m_serialIO->m_strPortName)==TRUE)
{
m_serialIO->OnEventOpen(TRUE);
}
else
{
m_serialIO->OnEventOpen(FALSE);
m_serialIO->SetPortActivate(FALSE);
}
}
else if (m_serialIO->GetPortActivateValue()==TRUE)
{
char message[MAX_MESSAGE]={0};
unsigned int lenBuff = MAX_MESSAGE;
unsigned long lenMessage;
if(serialCtrl().Read(message,lenBuff,lenMessage)==TRUE)
{
if(lenMessage>0)
m_serialIO->OnEventRead(message,lenMessage);
}
else
{
m_serialIO->SetProcessActivate(FALSE);
}
}
if (m_serialIO->GetSendActivateValue()==TRUE)
{
unsigned long nWritten;
if(serialCtrl().Write(m_serialIO->m_sendBuffer,m_serialIO->m_sendSize,nWritten)==TRUE)
{
m_serialIO->OnEventWrite(nWritten);
}
else
{
m_serialIO->OnEventWrite(-1);
}
m_serialIO->SetSendActivate(FALSE);
}
if (m_serialIO->m_bClosePort==TRUE)
{
if (serialCtrl().ClosePort()==TRUE)
{
m_serialIO->OnEventClose(TRUE);
}
else
{
m_serialIO->OnEventClose(FALSE);
}
m_serialIO->m_bClosePort=FALSE;
}
}
break;
}
return 0;
}
void SerialThread::ClosePort()
{
serialCtrl().ClosePort();
}
I guess that it is SerialThread run which an issues but I didn't find how solve it.
(After performance and others tools)
Are you some idea?
Thank you
I took a look at your code, and unfortunately the problem comes from the library/project you are using. Basically the all-in-one thread is just looping and never waiting anywhere, and this leads to 100% CPU consumption.
What you can do :
Add a Sleep(1-10) at the end of the inner while loop in the run() method. This method is the worst, it just patch the underlying problem.
Use another, better designed library.
Make your own library suited to your use.
Some advises to make your own serial com wrapper :
Everything you need to know about serial ports on Windows is here : Serial Communications.
An IO thread should always wait somewhere. It can be on a blocking IO call like ReadFile(), or on a Windows waitable object.
If you can, use overlapped IO, even if you don't use asynchronous calls. It will enable simultaneous read and write, and make the reads and writes cancellable (cleanly).
You only need a separate thread to read. And optionally another one to write via a message queue, if you want a completely asynchronous library.
Hy,
I'm writing my first Qt program and getting now in troubles with:
QObject::killTimer: timers cannot be stopped from another thread
QObject::startTimer: timers cannot be started from another thread
My program will communicate to a CANOpen bus for that I'm using the Canfestival Stack. The Canfestival will work with callback methods. To detects timeout in communication I setup a timer function (somehow like a watchdog). My timer package consist out of a "tmr" module, a "TimerForFWUpgrade" module and a "SingleTimer" module. The "tmr" module was originally C programmed so the static "TimerForFWUpgrade" methods will interface it. The "tmr" module will be part of a C programed Firmware update package.
The timer will work as follows. Before a message is sent I will call TMR_Set method. An then in my idle program loop with TMR_IsElapsed we check for a timer underflow. If TMR_IsElapsed I will do the errorhandling. As you see the TMR_Set method will be called continuously and restart the QTimer again and again.
The above noted errors are appearing if I start my program. Can you tell me if my concept could work? Why does this errors appear? Do I have to use additional threads (QThread) to the main thread?
Thank you
Matt
Run and Idle loop:
void run
{
// start communicate with callbacks where TMR_Set is set continously
...
while(TMR_IsElapsed(TMR_NBR_CFU) != 1);
// if TMR_IsElapsed check for errorhandling
....
}
Module tmr (interface to C program):
extern "C"
{
void TMR_Set(UINT8 tmrnbr, UINT32 time)
{
TimerForFWUpgrade::set(tmrnbr, time);
}
INT8 TMR_IsElapsed(UINT8 tmrnbr)
{
return TimerForFWUpgrade::isElapsed(tmrnbr);
}
}
Module TimerForFWUpgrade:
SingleTimer* TimerForFWUpgrade::singleTimer[NR_OF_TIMERS];
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent)
{
for(unsigned char i = 0; i < NR_OF_TIMERS; i++)
{
singleTimer[i] = new SingleTimer(parent);
}
}
//static
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
time *= TimerForFWUpgrade::timeBase;
singleTimer[tmrnbr]->set(time);
}
}
//static
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
if(true == singleTimer[tmrnbr]->isElapsed())
{
return 1;
}
else
{
return 0;
}
}
Module SingleTimer:
SingleTimer::SingleTimer(QObject* parent) : QObject(parent),
pTime(new QTimer(this)),
myElapsed(true)
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_setElapsed()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->setSingleShot(true);
}
void SingleTimer::set(unsigned int time)
{
myElapsed = false;
pTime->start(time);
}
bool SingleTimer::isElapsed()
{
QCoreApplication::processEvents();
return myElapsed;
}
void SingleTimer::slot_setElapsed()
{
myElapsed = true;
}
Use QTimer for this purpose and make use of SIGNALS and SLOT for the purpose of starting and stopping the timer/s from different threads. You can emit the signal from any thread and catch it in the thread which created the timer to act on it.
Since you say you are new to Qt, I suggest you go through some tutorials before proceeding so that you will know what Qt has to offer and don't end up trying to reinvent the wheel. :)
VoidRealms is a good starting point.
You have this problem because the timers in the static array is created in Thread X, but started and stopped in Thread Y. This is not allowed, because Qt rely on thread affinity to timeout timers.
You can either create, start stop in the same thread or use signal and slots to trigger start and stop operations for timers. The signal and slot solution is a bit problematic Because you have n QTimer objects (Hint: how do you start the timer at position i?)
What you can do instead is create and initialize the timer at position tmrnbr in
TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
singleTimer[tmrnbr] = new SingleTimer(0);
singleTimer[tmrnbr]->set(time);
}
which is executed by the same thread.
Futhermore, you don't need a SingleTimer class. You are using Qt5, and you already have all you need at your disposal:
SingleTimer::isElapsed is really QTimer::remainingTime() == 0;
SingleTimer::set is really QTimer::setSingleShot(true); QTimer::start(time);
SingleTimer::slot_setElapsed becomes useless
ThusSingleTimer::SingleTimer becomes useless and you dont need a SingleTimer class anymore
I got the errors away after changing my timer concept. I'dont use anymore my SingleTimer module. Before the QTimer I won't let timeout and maybe because of that I run into problems. Now I have a cyclic QTimer that times out every 100ms in slot function I will then count the events. Below my working code:
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent) : QObject(parent),
pTime(new QTimer(this))
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_handleTimer()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->start(100);
}
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
if(timeBase != 0)
{
myTimeout[tmrnbr] = time / timeBase;
}
else
{
myTimeout[tmrnbr] = 0;
}
myTimer[tmrnbr] = 0;
myElapsed[tmrnbr] = false;
myActive[tmrnbr] = true;
}
}
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
QCoreApplication::processEvents();
if(tmrnbr < NR_OF_TIMERS)
{
if(true == myElapsed[tmrnbr])
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0; // NOK
}
}
void TimerForFWUpgrade::slot_handleTimer()
{
for(UINT8 i = 0; i < NR_OF_TIMERS; i++)
{
if(myActive[i] == true)
{
myTimer[i]++;
if(myTimeout[i] < myTimer[i])
{
myTimer[i] = 0;
myElapsed[i] = true;
myActive[i] = false;
}
}
}
}
I've wrote a timer using std::thread - here is how it looks like:
TestbedTimer::TestbedTimer(char type, void* contextObject) :
Timer(type, contextObject) {
this->active = false;
}
TestbedTimer::~TestbedTimer(){
if (this->active) {
this->active = false;
if(this->timer->joinable()){
try {
this->timer->join();
} catch (const std::system_error& e) {
std::cout << "Caught system_error with code " << e.code() <<
" meaning " << e.what() << '\n';
}
}
if(timer != nullptr) {
delete timer;
}
}
}
void TestbedTimer::run(unsigned long timeoutInMicroSeconds){
this->active = true;
timer = new std::thread(&TestbedTimer::sleep, this, timeoutInMicroSeconds);
}
void TestbedTimer::sleep(unsigned long timeoutInMicroSeconds){
unsigned long interval = 500000;
if(timeoutInMicroSeconds < interval){
interval = timeoutInMicroSeconds;
}
while((timeoutInMicroSeconds > 0) && (active == true)){
if (active) {
timeoutInMicroSeconds -= interval;
/// set the sleep time
std::chrono::microseconds duration(interval);
/// set thread to sleep
std::this_thread::sleep_for(duration);
}
}
if (active) {
this->notifyAllListeners();
}
}
void TestbedTimer::interrupt(){
this->active = false;
}
I'm not really happy with that kind of implementation since I let the timer sleep for a short interval and check if the active flag has changed (but I don't know a better solution since you can't interrupt a sleep_for call). However, my program core dumps with the following message:
thread is joinable
Caught system_error with code generic:35 meaning Resource deadlock avoided
thread has rejoined main scope
terminate called without an active exception
Aborted (core dumped)
I've looked up this error and as seems that I have a thread which waits for another thread (the reason for the resource deadlock). However, I want to find out where exactly this happens. I'm using a C library (which uses pthreads) in my C++ code which provides among other features an option to run as a daemon and I'm afraid that this interfers with my std::thread code. What's the best way to debug this?
I've tried to use helgrind, but this hasn't helped very much (it doesn't find any error).
TIA
** EDIT: The code above is actually not exemplary code, but I code I've written for a routing daemon. The routing algorithm is a reactive meaning it starts a route discovery only if it has no routes to a desired destination and does not try to build up a routing table for every host in its network. Every time a route discovery is triggered a timer is started. If the timer expires the daemon is notified and the packet is dropped. Basically, it looks like that:
void Client::startNewRouteDiscovery(Packet* packet) {
AddressPtr destination = packet->getDestination();
...
startRouteDiscoveryTimer(packet);
...
}
void Client::startRouteDiscoveryTimer(const Packet* packet) {
RouteDiscoveryInfo* discoveryInfo = new RouteDiscoveryInfo(packet);
/// create a new timer of a certain type
Timer* timer = getNewTimer(TimerType::ROUTE_DISCOVERY_TIMER, discoveryInfo);
/// pass that class as callback object which is notified if the timer expires (class implements a interface for that)
timer->addTimeoutListener(this);
/// start the timer
timer->run(routeDiscoveryTimeoutInMilliSeconds * 1000);
AddressPtr destination = packet->getDestination();
runningRouteDiscoveries[destination] = timer;
}
If the timer has expired the following method is called.
void Client::timerHasExpired(Timer* responsibleTimer) {
char timerType = responsibleTimer->getType();
switch (timerType) {
...
case TimerType::ROUTE_DISCOVERY_TIMER:
handleExpiredRouteDiscoveryTimer(responsibleTimer);
return;
....
default:
// if this happens its a bug in our code
logError("Could not identify expired timer");
delete responsibleTimer;
}
}
I hope that helps to get a better understanding of what I'm doing. However, I did not to intend to bloat the question with that additional code.
I've a for loop that will launch processes in parallel every launched process will return a response back indicating that it is ready. I want to wait for the response and I'll abort if a certain timeout is reached.
Development environment is VS2008
Here is the pseudo code:
void executeCommands(std::vector<Command*> commands)
{
#pragma omp parallel for
for (int i = 0; i < commands.size(); i++)
{
Command* cmd = commands[i];
DWORD pid = ProcessLauncher::launchProcess(cmd->getWorkingDirectory(), cmd->getCommandToExcecute(), cmd->params);
//Should I wait for process to become ready?
if (cmd->getWaitStatusTimeout() > 0)
{
ProcessStatusManager::getInstance().addListener(*this);
//TODO: emit process launching signal
//BEGINNING OF QUESTION
//I don't how to do this part.
//I might use QT's QWaitCondition but if there is another solution in omp
//I'd like to use it
bool timedOut;
SOMEHANDLE handle = Openmp::waitWithTimeout(cmd->getWaitStatusTimeout(), &timedOut);
mWaitConditions[pid]) = handle;
//END OF QUESTION
if (timedOut)
{
ProcessStatusManager::getInstance().removeListener(*this);
//TODO: kill process
//TODO: emit fail signal
}
else
{
//TODO: emit process ready signal
}
}
else
{
//TODO: emit process ready signal
}
}
}
void onProcessReady(DWORD sourceProcessPid)
{
ProcessStatusManager::getInstance().removeListener(*this);
SOMEHANDLE handle = mWaitConditions[sourceProcessPid];
if (mWaitConditions[sourceProcessPid] != 0)
{
Openmp::wakeAll(handle);
}
}
As the comment above pointed out, Michael Suess did present a paper on adding this functionality to OpenMP. He is the last of several people that have proposed adding some type of wait function to OpenMP. The OpenMP language committee has taken the issue up several times. Each time it has been rejected because there are other ways to do this function already. I don't know Qt, but as long as the functions it provides are thread safe, then you should be able to use them.