Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::async analogue for specified thread

I need to work with several objects, where each operation may take a lot of time.

The processing could not be placed in a GUI (main) thread, where I start it.

I need to make all the communications with some objects on asynchronous operations, something similar to std::async with std::future or QtConcurrent::run() in my main framework (Qt 5), with QFuture, etc., but it doesn't provide thread selection. I need to work with a selected object (objects == devices) in only one additional thread always,

because:

  1. I need to make a universal solution and don't want to make each class thread-safe
  2. For example, even if make a thread-safe container for QSerialPort, Serial port in Qt cannot be accessed in more than one thread:

Note: The serial port is always opened with exclusive access (that is, no other process or thread can access an already opened serial port).

  1. Usually a communication with a device consists of transmit a command and receive an answer. I want to process each Answer exactly in the place where Request was sent and don't want to use event-driven-only logic.

So, my question.

How can the function be implemented?

MyFuture<T> fut = myAsyncStart(func, &specificLiveThread);

It is necessary that one live thread can be passed many times.

like image 948
Vladimir Bershov Avatar asked Jul 23 '26 18:07

Vladimir Bershov


1 Answers

Let me answer without referencing to Qt library since I don't know its threading API.

In C++11 standard library there is no straightforward way to reuse created thread. Thread executes single function and can be only joined or detachted. However, you can implement it with producer-consumer pattern. The consumer thread needs to execute tasks (represented as std::function objects for instance) which are placed in queue by producer thread. So if I am correct you need a single threaded thread pool.

I can recommend my C++14 implementation of thread pools as tasks queues. It isn't commonly used (yet!) but it is covered with unit tests and checked with thread sanitizer multiple times. The documentation is sparse but feel free to ask anything in github issues!

Library repository: https://github.com/Ravirael/concurrentpp

And your use case:

#include <task_queues.hpp>

int main() {
    // The single threaded task queue object - creates one additional thread.
    concurrent::n_threaded_fifo_task_queue queue(1);

    // Add tasks to queue, task is executed in created thread.
    std::future<int> future_result = queue.push_with_result([] { return 4; });

    // Blocks until task is completed.
    int result = future_result.get();

    // Executes task on the same thread as before.
    std::future<int> second_future_result = queue.push_with_result([] { return 4; });
}
like image 109
Rames Avatar answered Jul 26 '26 08:07

Rames