C++ (Qt)#include <iostream>#include "concurrent_loop.h"#include <list> int main(){ static constexpr int num_threads = 4; std::mutex print_mutex; std::list<std::function<void()>> workers; for (unsigned int i = 0; i < num_threads; ++i) workers.push_back([&]() { std::this_thread::sleep_for(std::chrono::seconds(1)); std::lock_guard<std::mutex> lk(print_mutex); std::cout << std::this_thread::get_id() << std::endl; }); int ntests = 3; auto loop_function = [&]() { std::cout << --ntests << "---------------------" << std::endl; return ntests == 0; }; concurrent_loop cloop(loop_function, workers); cloop.join(); return 0;}
Bash1402695822149121402695570368001402695738222081402695654295042---------------------1402695570368001402695654295041402695822149121402695738222081---------------------1402695738222081402695654295041402695570368001402695822149120---------------------
C++ (Qt)#include <vector>#include <functional>#include <thread>#include <mutex>#include <iostream> using namespace std; int main(){ static constexpr size_t num_threads = 4; mutex print_mutex; vector< function< void() > > workers; workers.reserve( num_threads ); for( size_t i = 0; i < num_threads; ++i) workers.push_back([&]() { this_thread::sleep_for( std::chrono::seconds( 1 ) ); lock_guard<mutex> lk( print_mutex ); cout << this_thread::get_id() << endl; }); const size_t ntests = 3; for( size_t n = 0; n < ntests; ++n ) { #pragma omp parallel for for( size_t i = 0; i < workers.size(); ++i ) workers[ i ](); std::cout << n << "---------------------" << std::endl; } return 0;}
C++ (Qt)if (--workersInProcess == 0) ...
C++ (Qt)struct Task : public QRunnable { Task( Data * data ) : mData(data) {} virtual void run( void ) { DoCalc(*mData); } Data * mData;}; // main threadQThreadPool * pool = QThreadPool::globalInstance();while (!solved) { // заряжаем данные расчетов std::vector<Data> data; for (size_t i = 0; i < num_tasks; ++i) data.push_back(Data(i)); // запускаем for (size_t i = 0; i < num_tasks; ++i) pool->start(new Task(&data[i])); // ждем когда сварится pool->waitForDone(); solved = AnalyzeResults(data);};
C++ (Qt)#ifndef THREAD_POOL_H#define THREAD_POOL_H #include <list>#include <queue>#include <thread>#include <mutex>#include <condition_variable>#include <atomic>#include <future>#include <memory>#include <functional> class thread_pool{public: thread_pool(unsigned int nthreads = 1) : m_is_stop(false) { for (unsigned int i = 0; i < nthreads; ++i) m_threads.push_back(std::thread(&thread_pool::worker, this)); } thread_pool(const thread_pool &) = delete; thread_pool(thread_pool &&) = delete; thread_pool & operator=(const thread_pool &) = delete; thread_pool & operator=(thread_pool &&) = delete; void join() { m_is_stop = true; m_loop_cv.notify_all(); for (auto & th : m_threads) { if (th.joinable()) th.join(); } } template<class F> auto add_task(F && work_function)->std::future<decltype(work_function())> { auto task_ptr = std::make_shared<std::packaged_task<decltype(work_function())()>>(std::forward<F>(work_function)); std::function<void()> wrapper_func = [task_ptr]() { (*task_ptr)(); }; { std::lock_guard<std::mutex> lock(m_mutex); m_queue.push(wrapper_func); } m_loop_cv.notify_one(); return task_ptr->get_future(); } private: std::atomic_bool m_is_stop; std::list<std::thread> m_threads; std::queue<std::function<void()>> m_queue; std::mutex m_mutex; std::condition_variable m_loop_cv; void worker() { while (!m_is_stop) { std::unique_lock<std::mutex> lock(m_mutex); m_loop_cv.wait(lock, [&]() { return !m_queue.empty() || m_is_stop; }); if (m_is_stop) return; std::function<void()> work_function(m_queue.front()); m_queue.pop(); lock.unlock(); work_function(); } } }; #endif // THREAD_POOL_H
C++ (Qt)#include <iostream> #include "thread_pool.h" int main(){ static constexpr size_t nthreads = 4; static constexpr size_t ntests = 3; static constexpr size_t ntasks = 12; std::mutex mutex; std::vector<std::future<void>> results(ntasks); thread_pool pool(nthreads); for (size_t i = 0; i < ntests; ++i) { for (size_t j = 0; j < ntasks; ++j) results[j] = pool.add_task([&]() { std::this_thread::sleep_for(std::chrono::seconds(1)); std::lock_guard<std::mutex> lk(mutex); std::cout << std::this_thread::get_id() << std::endl; }); for (size_t j = 0; j < results.size(); ++j) results[j].wait(); std::cout << i << "---------------------" << std::endl; } pool.join(); return 0;}
C++ (Qt)... { std::unique_lock<std::mutex> lock(m_cv_mutex); m_loop_cv.wait(lock, [&]() { std::lock_guard<std::mutex> lk(m_queue_mutex); return !m_queue.empty() || m_is_stop; }); }...