Implementing asynchronous delays - c++

What would be a smart way to implement something like the following?
// Plain C function for example purposes.
void sleep_async(delay_t delay, void (* callback)(void *), void * data);
That is, a means of asynchronously executing a callback after a delay. POSIX, for example, has a few functions that do something like this, but they are mostly for asynchronous I/O (see this for what I mean). What interests me about those functions how they are executed "as if" on a new thread, according to that manual page, where an implementation may choose to spawn "a single thread...to receive all notifications". I am aware that some may nonetheless choose to spawn a whole thread for each of them, and that stuff like this may require support from the OS itself, so this is just an example.
I already have a couple of ways I could implement this (e.g. priority queue of events sorted by wake time on a timer loop, with no need to start a thread at all), but I am wondering whether there already exists smart[er] or [more] complete implementations of what I want to accomplish. For example, maybe implementations of Task.Delay() from C♯ (and coroutines like it in other language environments) do something smart in minimizing the amount of thread spawning for getting asynchronous delays.
Why am I looking for something like this? As implied by the title, I'm looking for something asynchronous. The above signature is just a simple C example to illustrate roughly what POSIX does. I am implementing some C++20 coroutines for use with co_await and friends, with thread pools and whatnot. Scheduling anything that would end up synchronously waiting on something is probably a bad idea, as it would prevent otherwise free threads from doing any work. Spawning [and potentially immediately detaching] a new thread just to add in an asynchronous delay doesn't seem like a very smart idea, either. My timer loop idea could be okay, but that implies needing a predefined timer granularity, and overhead from the priority queue.
Edit
I neglected to mention any real set of target platforms, as a commenter mentioned. I don't expect to target anything outside the "usual" desktop platforms, so the quirks of embedded development are ignored. The way I plan to use asynchronous delays themselves this way does not necessarily require threading support (everything could just be on a timer loop), but threading will nonetheless be required and used in accord (namely thread pools on which coroutines would be scheduled).

The simple but inefficient way would be to spawn a thread, have it sleep for delay, and then call the callback. This can be done in just a few lines using std::async():
auto delayed_call = std::async(std::launch::async, [&]{
std::this_thread::sleep_for(delay);
callback(data);
});
As mentioned by Thomas Matthews, this requires support for threads. While it's fine for a one-off call, it's not efficient if you have many such delayed calls. Having a priority queue and an event loop or a dedicated thread to handle events in this queue, as you already mentioned, is probably the most efficient way to do it. If you are looking for a library that implements this, then have a look at boost::asio.
As for using C++20 coroutines, I do not think that this will make something like your sleep_async() any easier. However, an event loop could be implemented on top of it.

A smart way? You mean really, really smart? That would be my own implementation, of course. You know about POSIX timers, you probably know about linux timers and the various hacks involving std::thread. But, more seriously, what you require sounds mostly to the tune of something like libeio, or libuv - both of these provide callbacks. It depends on what you can afford in binary size and whether you like the particular abstractions a library offers. The 2 libraries seem to be evolved versions of libevent and libev, libevent being the progenitor of them all.
Creating a std::thread instance involves allocating a stack frame, at the very least, which is by no means cheap.

Related

Rewriting multi-threaded event-driven C++ program to use single-threaded boost::asio

I am working on refactoring a large code base responsible for IO operations. Currently the program is comprised of a number of threads, each of which waits for proprietary events to be received. Events are posted to a global event queue and are received by all threads (a global event dispatcher calls an event handler function for every thread and that thread determines whether or not it should do something based on the event type and, if necessary, adds that event to its own work queue).
This architecture has a lot of overhead, both due to having a lot of threads (around 12 on a single arm core) which are mostly sleeping and due to the work queues. It also requires a few hundred different event classes which reduces maintainability.
I would like to replace this event based architecture with a single threaded boost asio methodology but am unsure of what paradigm I should use to do this. I think boost::io_service might be the best but perhaps coroutines, fibers, or something else would be better.
Does anyone have any suggestions what boost::asio paradigm would result in the smoothest transition when moving away from an event queue? I am looking for something that will improve code maintainability rather than making the code completely incomprehensible in exchange for reduced overhead.
This looks promising, but the coroutine syntax is a bit scary and it is going to be hard to sell to the rest of my team:
http://www.boost.org/doc/libs/1_57_0/libs/coroutine/doc/html/coroutine/motivation.html
You could use boost.fiber - it provides an API like std::thread.
You do not necessarily need boost.asio

Periodically call a C function without manually creating a thread

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.

It's legal to mix c++0x threads with gio GCancellable?

If I'm not wrong there is no easy way to make a c++0x thread cancellable. I'm wondering if it's legal to use GCancellable mixing it with c++0x thread.
If the answer is
No
I guess I should use glib threads or it's not so legal too?
I am not very familiar with GCancellable. After a quick read through, it appears to be a hierarchical notification system.
If that is the case then yes you can easily mix GCancellable with std::thread.
There is no easy way to make a std::thread cancellable.
This is wrong.
There is no non-zero cost way to make all std::threads cancellable.
This is correct.
The problem is providing a general solution. Notification is easy enough. The hard part is making sure the thread sees the notification. The thread may be blocked on a mutex or IO. You cannot just kill the thread. All sorts of bad can occur.
Each individual implementation is free to implement their own cancellation system tailored to you particular needs.
If you need to be interruptable from a blocking mutex, make sure you only use timed_mutexes, and that you call g_cancellable_is_cancelled frequently enough that your thread will cancel as needed.
You mean something like boost's interruptible threads?
This aspect didn't make it into the standard but you can derive from std::thread to offer a protected check_interrupted() method which throws if someone called a public interrupt() method.
I wouldn't bother mixing with Gnome's thread constructs. Sounds like more trouble than it's worth.

Using asynchronous method vs thread wait

I have 2 versions of a function which are available in a C++ library which do the same task. One is a synchronous function, and another is of asynchronous type which allows a callback function to be registered.
Which of the below strategies is preferable for giving a better memory and performance optimization?
Call the synchronous function in a worker thread, and use mutex synchronization to wait until I get the result
Do not create a thread, but call the asynchronous version and get the result in callback
I am aware that worker thread creation in option 1 will cause more overhead. I am wanting to know issues related to overhead caused by thread synchronization objects, and how it compares to overhead caused by asynchronous call. Does the asynchronous version of a function internally spin off a thread and use synchronization object, or does it uses some other technique like directly talk to the kernel?
"Profile, don't speculate." (DJB)
The answer to this question depends on too many things, and there is no general answer. The role of the developer is to be able to make these decisions. If you don't know, try the options and measure. In many cases, the difference won't matter and non-performance concerns will dominate.
"Premature optimisation is the root of all evil, say 97% of the time" (DEK)
Update in response to the question edit:
C++ libraries, in general, don't get to use magic to avoid synchronisation primitives. The asynchronous vs. synchronous interfaces are likely to be wrappers around things you would do anyway. Processing must happen in a context, and if completion is to be signalled to another context, a synchronisation primitive will be necessary to do that.
Of course, there might be other considerations. If your C++ library is talking to some piece of hardware that can do processing, things might be different. But you haven't told us about anything like that.
The answer to this question depends on context you haven't given us, including information about the library interface and the structure of your code.
Use asynchronous function because will probably do what you want to do manually with synchronous one but less error prone.
Asynchronous: Will create a thread, do work, when done -> call callback
Synchronous: Create a event to wait for, Create a thread for work, Wait for event, On thread call sync version , transfer result, signal event.
You might consider that threads each have their own environment so they use more memory than a non threaded solution when all other things are equal.
Depending on your threading library there can also be significant overhead to starting and stopping threads.
If you need interprocess synchronization there can also be a lot of pain debugging threaded code.
If you're comfortable writing non threaded code (i.e. you won't burn a lot of time writing and debugging it) then that might be the best choice.

Reading information from a worker thread efficiently

I'm writing some computer vision software, here's a brief description to help clarify the problem:
I have 3 cameras, each running at 60fps
Each camera has it's own thread, to utilise multiple cores
Each thread waits for a new frame to arrive, does some processing on the image, saves the result and waits for the next frame
My main program creates these thread, using boost, following this tutorial: http://blog.emptycrate.com/node/282
I am currently polling the threads in a tight loop to retrieve the data, e.g.:
while(1) {
for(i=0; i<numCams; i++) {
result[i] = cam[i]->getResult();
}
//do some stuff
}
This seems silly. Is there a standard way of letting the main program know that there is a new result and that it needs to be retrieved?
Thanks!
Yes, you need to use condition variables (AKA events).
Yes, you need to use synchronization. There are many forms depending on what you're using as a threading API, however the simplest is probably a condition variable.
What you need is a thread pool. The number of cameras isn't necessary the same as the optimal number of threads. Thread pool is optimized for performance. Then, you don't need to wait for condition or poll the jobs, you enqueue the jobs (most often it's std::function<void()>) in the thread pool, and that job object should perform all the required work. Use binders (std::bind) or lambda functions to create a job object.
In your case you are talking to hardware, so you may need to use whatever facilities your camera API provides for asynchronous notification of incomming data. Usually that will be some kind of callback you provide, or occasionally something like a Windows Event handle or Unix signal.
In general if you meant "standard" as in "part of the C++ standard", no. You need to use your OS's facilites for interprocess (or thread) condition signalling.
Note that if we were talking Ada (or Modula-2, or many other modern systems programming languages) the answer would have been "yes". I understand there is some talk of putting concurrency support of some kind into a future C++ standard.
In the meantime, there is the boost::thread library for doing this kind of thing. That isn't exactly "standard", but for C++ it is pretty close. I think for what you are trying to do, condition variables might be what you want. However, if you read over the whole facility, other simpler designs may occur to you.
I know this sounds a little odd, however consider using a boost::asio::io_service it's as close to a threadpool as you get currently. When you've captured an image, you can post to this service and the service can then execute a handler asynchronously to handle your image data.