I am implementing a function in library which takes a while (up to a minute). It initialize a device. Now generally any long function should run in its own thread and report to main thread when it completes but I am not sure since this function is in library.
My dilemma is this, even if I implement this in a separate thread, another thread in the application has to wait on it. If so why not let the application run this function in that thread anyways?
I could pass queue or mailbox to the library function but I would prefer a simpler mechanism where the library can be used in VB, VC, C# or other windows platforms.
Alternatively I could pass HWND of the window and the library function can post message to it when it completes instead of signaling any event. That seems like most practical approach if I have to implement the function in its own thread. Is this reasonable?
Currently my function prototype is:
void InitDevice(HANDLE hWait)
When initialization is complete than I signal bWait. This works fine but I am not convinced I should use thread anyways when another secondary thread will have to wait on InitDevice. Should I pass HWNDinstead? That way the message will be posted to the primary thread and it will make better sense with multithreading.
In general, when I write library code, I normally try to stay away from creating threads unless it's really necessary. By creating a thread, you're forcing a particular threading model on the application. Perhaps they wish to use it from a very simplistic command-line tool where a single thread is fine. Or they could use it from a GUI tool where things must be multi-threaded.
So, instead, just give the library user understanding that a function call is a long-term blocking call, some callback mechanism to monitor the progress, and finally a way to immediately halt the operation which could be used by a multi-threaded application.
What you do want to claim is being thread safe. Use mutexes to protect data items if there are other functions they can call to affect the operation of the blocking function.
Related
I would like to have your opinion for this general technical concept. (I am working on microsoft windows OS)
There is a Process, this process creates multiple threads for different tasks.
Main process: it is a windows service written by C# code.
There are several threads that are create inside the main process: Thread_01, Thread_02, ...
Inside Thread_01: There is a Wrapper dll written in managed C++ to consume DLL_01. (DLL_01 is a dll written by me in native C++ code, that provides some APIs: Add, Remove, Connect)
Add and Remove can run very fast, but Connect may take more than 10 seconds and blocks the caller until it finishes.
I am thinking to use std::async to do the Connect function code, and send the result through a callback to the caller (main process).
Is it a good approach? I heard we cannot create or it is better not to create any thread inside inner threads, is it true? If so, how about std::async ?
Any recommendation is appreciated.
Thanks in advance,
None of what you describe makes the use of threads inacceptable for your code.
As usual, threads have issues that need to be cared for:
Data races due to access to shared data.
Problems of ownership of resources is now not just "Who own what?" but "Who and when owns what?".
When a thread is blocked and you want to abort this operation, how do you cancel it without causing issues down the line? In your case, you must avoid calling the callback, when the receiver doesn't exist any more.
Concerning your approach of using a callback, consider std::future<> instead. This takes care of a few of the issues above, though some are only shifted to the caller instead.
We are trying to write a portable shared library that makes use of some Qt classes for convenience (mainly QTimer and QTcpSocket); no GUI stuff, though. The according signal/slot connections appear to require some Qt event loop, so we "prime" a QCoreApplication as outlined in this answer. Accordingly, we set up a worker object that does the heavy lifting and move it to a QThread.
The problem we run into now is that the queued connections between the QThread's owner object (within the main thread) and the worker object within the QThread seem to never get handled on Linux systems, at least as long as the program that implements our library does not provide any further Qt event loop of its own in the main thread. This is not very helpful, since the data passed from the worker to the main thread should be passed further using some callback functions, which now never get called, though.
My question is thus: is there a way to get an event loop to work in the library main thread without locking it or the host program up (which seems to be the case when just putting a QCoreApplication::exec() or similar there)? Or will we have to set up a different inter-thread communication scheme (independent from Qt) in order to deal with these data transfers?
Since we do not know if the host software is going to run on a QApplication or not, ideally I'd also have a check for that before setting up a main thread event loop. Is a simple if(qApp != nullptr) enough for that?
P.S.: A few things I tried but which did not work for me, either:
Settings up a QEventLoop in a std::thread launched from the main thread (probably not working because still not in the main thread)
Setting up a QEventLoop in the main thread class and triggering its processEvents() function periodically using a QTimer (probably not working due to the missing event loop for the QTimer::timeout signal in the main function)
Starting the QCoreApplication in a std::thread (gives a run-time warning on Windows that QCoreApplication should be started in the main thread)
In Qt parlance, a callback is called Qt::DirectConnection. But of course those callbacks will run on your worker thread. But that’d be the case with any other library that uses callbacks, so Qt is not a problem here, and neither is your code: the basic idea has this property.
If the host application is not using an event loop (any event loop, not necessarily Qt’s), then there’s nothing you can do other than polling – see below.
If the host application runs an X11 event loop, then you need to ensure that your copy of Qt is using the same underlying event loop as the host application. Usually, this would be the glib’s event loop, and then it should work automagically. Otherwise, you’ll need to pass to the user the file descriptor of the synchronization primitive used by Qt’s event loop, and the user will need to integrate it into their event loop. You’ll face the same problem whether you use Qt or not: rolling your own communication method won’t fix it, since you still need a waitable primitive that will interoperate with whatever event loop the user is using.
The user can of course poll for callbacks whenever they feel like it: expose a mainPoll() method that forwards to QCoreApplication::processEvents().
Despite accepting another answer (which I deem more correct), I'd still like to mention a workaround that worked surprisingly well: We actually managed to get around the event loop/thread problems on most systems by connecting the worker thread signals with lambda functions in constructor of the class that sets up the worker.
Now, I doubt that this behaviour is properly thread-safe, and having relatively lengthy lambda functions declared in connect function calls is certainly not good style. But in case anyone else ends up struggling with this issue, this may be a short-term solution or (temporary) workaround.
I have implemented a WebSocket handler in C++ and I need to send ping messages once in a while. However, I don't want to start one thread per socket/one global poll thread which only calls the ping function but instead use some OS functionality to call my timer function. On Windows, there is SetTimer but that requires a working message loop (which I don't have.) On Linux there is timer_create, which looks better.
Is there some portable, low-overhead method to get a function called periodically, ideally with some custom context? I.e. something like settimer (const int millisecond, const void* context, void (*callback)(const void*))?
[Edit] Just to make this a bit clearer: I don't want to have to manage additional threads. On Windows, I guess using CreateThreadpoolTimer on the system thread pool will do the trick, but I'm curious to hear if there is a simpler solution and how to port this over to Linux.
If you are intending to go cross-platform, I would suggest you use a cross platform event library like libevent.
libev is newer, however currently has weak Win32 support.
If you use sockets, you can use select, to wait sockets events with timeout,
and in this loop calc time and call callback in suitable time.
If you are looking for a timer that will not require an additional thread, let you do your work transparently and then call the timer function at the appropriate time in the same thread by pre-emptively interrupting your application, then there is no such portable thing.
The first reason is that it's downright dangerous. That's like writing a multi-threaded application with absolutely no synchronization. The second reason is that it is extremely difficult to have good semantics in multi-threaded applications. Which thread should execute the timer callback?
If you're writing a web-socket handler, you are probably already writing a select()-based loop. If so, then you can just use select() with a short timeout and check the different connections for which you need to ping each peer.
Whenever you have asynchronous events, you should have an event loop. This doesn't need to be some system default one, like Windows' message loop. You can create your own. But you should be using it.
The whole point about event-based programming is that you are decoupling your code handling to deal with well-defined functional fragments based on these asynchronous events. Without an event loop, you are condemning yourself to interleaving code that get's input and produces output based on poorly defined "states" that are just fragments of procedural code.
Without a well-defined separation of states using an event-based design, code quickly becomes unmanageable. Because code pauses inside procedures to do input tasks, you have lifetimes of objects that will not span entire procedure scopes, and you will begin to write if (nullptr == xx) in various places that access objects created or destroyed based on events. Dispatch becomes comnbinatorially complex because you have different events expected at each input point and no abstraction.
However, simply using an event loop and dispatch to state machines, you've decreased handling complexity to basic management of handlers (O(n) handlers versus O(mn) branch statements with n types of events and m states). You decouple handling but still allow for functionality to change depending on state. But now these states are well-defined using state classes. And new states can be added if the requirements of the product change.
I'm just saying, stop trying to avoid an event loop. It's a software pattern for very important reasons, all of which have to do with producing professional, reusable, scalable code. Use Boost.ASIO or some other framework for cross platform capabilities. Don't get in the habit of doing it wrong just because you think it will be less of an effort. In the end, even if it's not a professional project that needs maintenance long term, you want to practice making your code professional so you can do something with your skills down the line.
I've been playing with a DataBus-type design for a hobby project, and I ran into an issue. Back-end components need to notify the UI that something has happened. My implementation of the bus delivers the messages synchronously with respect to the sender. In other words, when you call Send(), the method blocks until all the handlers have called. (This allows callers to use stack memory management for event objects.)
However, consider the case where an event handler updates the GUI in response to an event. If the handler is called, and the message sender lives on another thread, then the handler cannot update the GUI due to Win32's GUI elements having thread affinity. More dynamic platforms such as .NET allow you to handle this by calling a special Invoke() method to move the method call (and the arguments) to the UI thread. I'm guessing they use the .NET parking window or the like for these sorts of things.
A morbid curiosity was born: can we do this in C++, even if we limit the scope of the problem? Can we make it nicer than existing solutions? I know Qt does something similar with the moveToThread() function.
By nicer, I'll mention that I'm specifically trying to avoid code of the following form:
if(! this->IsUIThread())
{
Invoke(MainWindowPresenter::OnTracksAdded, e);
return;
}
being at the top of every UI method. This dance was common in WinForms when dealing with this issue. I think this sort of concern should be isolated from the domain-specific code and a wrapper object made to deal with it.
My implementation consists of:
DeferredFunction - functor that stores the target method in a FastDelegate, and deep copies the single event argument. This is the object that is sent across thread boundaries.
UIEventHandler - responsible for dispatching a single event from the bus. When the Execute() method is called, it checks the thread ID. If it does not match the UI thread ID (set at construction time), a DeferredFunction is allocated on the heap with the instance, method, and event argument. A pointer to it is sent to the UI thread via PostThreadMessage().
Finally, a hook function for the thread's message pump is used to call the DeferredFunction and de-allocate it. Alternatively, I can use a message loop filter, since my UI framework (WTL) supports them.
Ultimately, is this a good idea? The whole message hooking thing makes me leery. The intent is certainly noble, but are there are any pitfalls I should know about? Or is there an easier way to do this?
I have been out of the Win32 game for a long time now, but the way we used to achieve this was by using PostMessage to post a windows message back to the UI thread and then handle the call from there, passing the additional info you need in wParam/lParam.
In fact I wouldn't be surprised if that is how .NET handles this in Control.Invoke.
Update: I was currios so I checked with reflector and this is what I found.
Control.Invoke calls MarshaledInvoke which does a bunch of checkes etc. but the interesting calls are to RegisterWindowMessage and PostMessage. So things have not changed that much :)
A little bit of follow-up info:
There are a few ways you can do this, each of which has advantages and disadvantages:
The easiest way is probably the QueueUserAPC() call. APCs are a bit too in-depth to explain, but the only drawback is they may run when you're not ready for them if the thread gets put into an alertable wait state accidently. Because of this, I avoided them. For short applications, this is probably OK.
The second way involves using PostThreadMessage(), as previously mentioned. This is better than QueueUserAPC() in that your callbacks aren't sensitive to the UI thread being in an alertable wait state, but using this API has the problem of your callbacks not being run at all. See Raymond Chen's discussion on this. To get around this, you need to put a hook on the thread's message queue.
The third way involves setting up an invisible, message-only window whose WndProc calls the deferred call, and using PostMessage() for your callback data. Because it is directed at a specific window, the messages won't get eaten in modal UI situations. Also, message-only windows are immune to system message broadcasts (thus preventing message ID collisions). The downside is it requires more code than the other options.
I have a main process that uses a single thread library and I can only the library functions from the main process. I have a thread spawned by the parent process that puts info it receives from the network into a queue.
I need to able to tell the main process that something is on the queue. Then it can access the queue and process the objects. The thread cannot process those objects because the library can only be called by one process.
I guess I need to use pipes and signals. I also read from various newsgroups that I need to use a 'self-trick' pipe.
How should this scenario be implemented?
A more specific case of the following post:
How can unix pipes be used between main process and thread?
Why not use a simple FIFO (named pipe)? The main process will automatically block until it can read something.
If it shouldn't block, it must be possible to poll instead, but maybe it will suck CPU. There probably exists an efficient library for this purpose.
I wouldn't recommend using signals because they are easy to get wrong. If you want to use them anyway, the easiest way I've found is:
Mask all signals in every thread,
A special thread handles signals with sigwait(). It may have to wake up another thread which will handle the signal, e.g. using condition variables.
The advantage is that you don't have to worry anymore about which function is safe to call from the handler.
The "optimal" solution depends quite a bit on your concrete setup. Do you have one process with a main thread and a child thread or do you have one parent process and a child process? Which OS and which thread library do you use?
The reason for the last question is that the current C++03 standard has no notion of a 'thread'. This means in particular that whatever solution your OS and your thread library offer are platform specific. The most portable solutions will only hide these specifics from you in their implementation.
In particular, C++ has no notion of threads in its memory model, nor does it have a notion of atomic operations, synchronization, ordered memory accesses, race conditions etc.
Chances are, however, that whatever library you are using already provides a solution for your problem on your platform.
I highly suggest you used a thread-safe queue such as this one (article and source code). I have personally used it and it's very simple to use. The API consist in simple methods such as push(), try_pop(), wait_and_pop() and empty().
Note that it is based on Boost.Thread.