Boost library and CreateThread win API - multithreading

I have a class such as :
class MyStreamReader
{
public:
MyStreamReader(MyPramameter myPram) {.....}
~MyStreamReader() {}
DWORD WINAPI ReaderThread(LPVOID *lpdwThreadParam )
{
//....
}
};
and i want to call ReaderThread with WinAPI CreateThread. But CreateThread wants ReaderThread function wants a static function.
In some forms it is said that this is possible with boost library such as :
CreateThread(NULL, 0, boost::bind(&MyStreamReader::ReaderThread,this),
(void*)&myParameterObject), 0, NULL);
But i got compilation error:
'CreateThread' : cannot convert parameter x from 'boost::_bi::bind_t<R,F,L>'
to 'LPTHREAD_START_ROUTINE'
So as a result my questions:
Is it possible to call non-static function of a class from
CreateThread using boost lib(or any other method)
If not any C++ THREADing librray you may recomend(for visual C++) which i can call-run non static member function of a class as a thread?
Best Wishes
Update:
So first question: It seesm that it is impossible to call non-static c++ member function from CreateThread win API...
So any recomandations for C++ Multithreading lib whic is possible to call non-static functions as threads...
Update 2:
Well i try boost thread lib...seems it works...
MyStreamReader* streamReader = new MyStreamReader(myParameters);
boost::thread GetStreamsThread
( boost::bind( &MyStreamReader::ReaderThread, streamReader ) );
or (no need for bind)
boost::thread GetStreamsThread(&MyStreamReader::ReaderThread, streamReader);
AND in order to use boost::thread i update my class definition as:
class MyStreamReader
{
public:
MyStreamReader(MyPramameter myPram) {.....}
~MyStreamReader() {}
void ReaderThread()
{
//....
}
};

One common answer to this is to use a static "thunk":
class Worker
{
public :
static DWORD Thunk(void *pv)
{
Worker *pThis = static_cast<Worker*>(pv);
return pThis->DoWork();
}
DWORD DoWork() { ... }
};
...
int main()
{
Worker worker;
CreateThread(NULL, 0, &Worker::Thunk, &worker);
}
You can, of course, pack more parameters into your call to pv. Just have your thunk sort them out correctly.
To answer your question more directly, boost::bind doesn't work with the Winapi that way. I would advise using boost::thread instead, which does work with boost::bind (or, if you have a C++0x compiler, use std::thread with std::bind).

Related

QSerialPort with no GUI, no thread: QObject::startTimer: Timers can only be used with threads started with QThread

I'm doing a DLL with no GUI (TEMPLATE = lib), using QSerialPort. I don't create threads and I don't need any: I have no GUI and having a blocking serial port operation is no problem, it is what I want.
When doing:
while (!serial_uart->isWritable());
while (!serial_uart->write(frame));
I get:
QObject::startTimer: Timers can only be used with threads started with QThread
Question: how to use QSerialPort in a library without GUI without triggering this error?
Note: I first thought the problem was coming from serial_uart->waitForReadyRead(timeout) but even without this and only serial_uart->write() I already have this problem.
Minimal reproducible DLL example:
test.cpp
#include "test.h"
extern "C" {
__declspec(dllexport) Test* new_Test() { return new Test(); }
__declspec(dllexport) void DoTest(Test *t) { t->DoTest(); }
}
Test::Test() :QObject()
{
qDebug("Hello");
}
void Test::DoTest()
{
this->serialport = new QSerialPort();
this->serialport ->setPortName("COM12");
this->serialport->setBaudRate(QSerialPort::Baud19200);
this->serialport->open(QIODevice::ReadWrite);
while (!this->serialport->isWritable());
while (!this->serialport->write("hello"));
}
test.h
#include <QSerialPort>
class Test : public QObject
{
Q_OBJECT
public:
Test();
void DoTest();
QSerialPort *serialport;
};
test.pro
TEMPLATE = lib
TARGET = test
QT += serialport
INCLUDEPATH += .
HEADERS += test.h
SOURCES += test.cpp
When I call the release/test.dll from Python I have this:
from ctypes import *
dll = CDLL(r"release\test.dll")
dll.new_Test.restype = c_void_p
dll.new_Test.argtypes = []
dll.DoTest.restype = None
dll.DoTest.argtypes = [c_void_p]
t = dll.new_Test()
dll.DoTest(t)
Hello
QObject::startTimer: Timers can only be used with threads started with QThread
Most of the QIODevice based classes (like Qt sockets or serial port) want to live in a Qt based thread and also their functions needs to be called from the same thread where the object was created.
For that reason I've usually solved this by:
Create wrapper class (QObject based with Q_OBJECT macro for signal/slot functionality) for the QIODevice based class you are about to use. For each function you are planning on using create a slot function on your wrapper class which then calls the equivalent funtion in the QIODevice:
qint64 MySerialPort::write(const QByteArray &data)
{
// m_serialPort is created with new QSerialPort in constructor of MySerialPort.
return m_serialPort->write(data);
}
Create a QThread class that in its run function creates an instance of MySerialPort (with new MySerialPort) and just calls exec() after that. Now MySerialPort lives in an event loop and is able to send and receive signals/slots.
void MySerialPortThread::run()
{
m_serialPort = new MySerialPort();
exec();
delete m_serialPort; // Automatic deletion after thread is stopped.
}
The thread could also return a pointer to the instance for easier access from outside to connect signals and slots.
MySerialPort* MySerialPortThread::serialPort()
{
return m_serialPort; // Instance of MySerialPort class
}
In your main code create signals that match the slots of the MySerialPort and connect them.
signals:
qint64 writeSerial(const QByteArray& data);
void MyMainClass::connectSignalsAndSlots()
{
MySerialPort* serialPort = m_serialThread->serialPort();
connect(this, &MyMainClass::writeSerial, serialPort, &MySerialPort::write, Qt::BlockingQueuedConnection); // Use either QueuedConnection or BlockingQueuedConnection to force the execution of the slot to the MySerialThread.
}
Emit the signals to access the QSerialPort.
emit writeSerial(dataByteArray);

How to open a thread in MFC to run a cuda function?

I now change my cuda program into an MFC project, I wrote the function of .cu as an interface function, So I can call it in MFC's dlg,Because I now use the UI thread call, I want to open a work thread to call, but failed.I am making AfxBeginThread, but it does not recognize my interface function.
I use vs2013, win7.
my interface function like this:
extern "C" float solveGPU(M_args Parameter_, double Mtime)
You could AfxBeginThread use but you have to call yout function from a new function or a static method with he following prototype:
UINT __cdecl MyControllingFunction( LPVOID pParam );
like this:
UINT __cdecl SolveGPUThreadFunction( LPVOID pParam )
{
YourDialogClass* pThis = (YourDialogClass*)(pParam);
pThis->result= solveGPU(pThis->Parameter_, pThis->Mtime);
}
and pass this pointer of your dialog as pParam of AfxBeginThread:
CWinThread* pCUDAThread = AfxBeginThread(&SolveGPUThreadFunction, this);
But you can think about using the std::thread instead.

Why console app hangs when using a shared dll that containg static variable that use mutex?

I have a shared dll library that contains a class as below :
inside A.dll >> Header File :
class API ErrorHandler
{
public:
ErrorHandler();
virtual ~ErrorHandler();
protected:
static ErrorHandler* defaultHandler();
private:
static ErrorHandler* _pHandler;
static std::mutex _mutex;
};
source(.cpp)
ErrorHandler* ErrorHandler::_pHandler = ErrorHandler::defaultHandler();
std::mutex ErrorHandler::_mutex;
ErrorHandler::ErrorHandler()
{
}
ErrorHandler::~ErrorHandler()
{
}
ErrorHandler* ErrorHandler::defaultHandler()
{
static SingletonHolder<ErrorHandler> sh;
return sh.get(); **<<====== here we get hanged** see the declaration of get
}
SingletoneHolder header file
template <class S>
class SingletonHolder
{
public:
SingletonHolder():
_pS(0)
{
}
~SingletonHolder()
{
delete _pS;
}
S* get()
{
std::lock_guard<std::mutex> lock(_m); <===== cause thread hang
if (!_pS) _pS = new S;
return _pS;
}
private:
S* _pS;
std::mutex _m;
};
After building the above code (every thing related to compiler setting configured correctly) now I want to use it in my console app.
After running console app, app hangs and never reach to main function.
Why std::lock_guard<std::mutex> lock(_m); hangs and prevent main thread to continue executing?
What is alternative?
I am using VS2013 Update5.
content of main file :
#include "ErrorHandler" <== when remove this include app run correctly
#include <iostream>
int main()
{
getchar();
return 0;
}
First, you should post exact contents of the main - with an empty main everything works. Things go south when the ErrorHandler class is being instantiated inside main.
Second, the initialization of your static members occurs inside __DllMainCRTStartup and as stated in the SO question I marked as duplicate, MSDN states that using synchronization primitives from __DllMainCRTStartup can cause a deadlock. A possible solution is to switch to a critical secion.

How to use clang thread annotations with a RAII style try-lock?

I would like to wrap the following code with clang thread annotations:
std::mutex mutex;
int counter = 0; // should be accessed while the mutex is locked
std::unique_lock<std::mutex> lock(mutex, std::try_to_lock);
if (lock) {
++counter;
}
I want both to use a RAII lock (std::unique_guard) and I also would like to add thread annotations to this code.
class __attribute__((capability("mutex"))) Mutex {
public:
Mutex() = default;
std::mutex &getInternalMutex() { return m_mutex; }
private:
std::mutex m_mutex{};
};
class __attribute__((scoped_lockable)) TryLock {
public:
TryLock(Mutex &mutex)
// PROBLEM HERE: __attribute__((acquire_capability(mutex)))
// is not suitable (lock may fail) but
// __attribute__((try_acquire_capability(true, mutex)))
// cannot be used neither (requires to be used in a method
// returning whether the lock succeed or not)
: m_try_lock(mutex.getInternalMutex(), std::try_to_lock) {}
~TryLock() __attribute__((release_capability)) = default;
bool isLocked() const {
return !!m_try_lock;
}
private:
std::unique_lock<std::mutex> m_try_lock;
};
clang only provides try_acquire_capability which is not suitable here (as it should be used for a function returning a boolean indicating if the lock succeeded or not).
What would be the correct way to annotate this lock?

starting std::thread with anonymous class call

I am curious as to how to correctly start a std::thread using an anonymous class call.
With the below code, if my class only having 1 member variable and I call std::thread td(someclass(shared_mutex)); I get a compiler warning of warning
C4930: 'std::thread td(someclass)': prototyped function not called (was a variable definition intended?)
However, if I add a second member variable as below and call it with
std::thread td(someclass(shared_mutex,x));
I get an error with error C2064: term does not evaluate to a function taking 0 arguments.
class someclass
{
private:
std::mutex& shared_mutex;
int x;
public:
someclass(std::mutex& init_mutex, int init_x) :
shared_mutex(init_mutex),
x(init_x)
{}
//...
};
int main()
{
std::mutex shared_mutex;
int x = 10;
std::thread td(someclass(shared_mutex,x));
td.join();
return 0;
}
The only way around this is by creating an
void operator()()
{}
within the class, but is that the correct method, just to have some kind of starting function for the thread reference or am I missing some other point here? I thought the constructor would be resolver for that?
Try using { and } syntax to construct your object to avoid veximg parses as a function declaration.
std::thread td(someclass(shared_mutex,x))
becomes
std::thread td{someclass{shared_mutex,x}}
It seems that you want your thread to execute the long-running constructor of someclass and then immediately discard the newly constructed someclass. This can be done by passing the thread constructor a function object that does just that:
int main()
{
std::mutex shared_mutex;
int x = 10;
std::thread td([&]{someclass(shared_mutex,x);});
td.join();
return 0;
}
Be warned: constructing a new thread is a hugely expensive operation, so you should avoid casually spawning new threads if you have the ability to instead reuse existing threads, unless you are only going to create new threads very infrequently.

Resources