2017-07-22 5 views
0

私は並列に動作する別のオブジェクトを作成するクラスを設計しています。この並列オブジェクトはGMainLoopを実行し、さまざまなイベント(この場合はDBus)を待ち受けます。私の問題は、GMainLoopで実行中のスレッドと通信する方法がわかりません。私はそのスレッドとの通信の方法をGLibに強制しますか?うまくいけば、私は結局、GLibへの私の依存を取り除くことができるように、標準ライブラリに頼っています。ここに私が達成しようとしているもののおもちゃの例があります:C++ 14とGLib(GDBus)を使用したスレッド通信

// Example program 
#include <iostream> 
#include <thread> 
#include <memory> 

#include <glib.h> 

class ParallelTask 
{ 
public: 
ParallelTask() { 
    std::cout << "I am alive!\n"; 

    // initialize _mainLoop (allocate, add signals, set priority, etc) 
    // ... 

    g_main_loop_run(_mainLoop); 
}; 
~ParallelTask() { 
    std::cout << "I am dead!\n"; 

    // Misc cleanup 
    // ... 

    g_main_loop_quit(_mainLoop); 
} 
private: 
GMainLoop* _mainLoop; 
}; 

class TaskManager 
{ 
public: 
TaskManager() = default; 
~TaskManager() {join();} 

void startTask() { 

    _thread = std::thread([this](){_task = std::make_unique<ParallelTask>();}); 
} 
void stopTask() { 
    //??? Need to send message to Parallel task telling it to shut down 
    join(); 
} 

private: 
void join() { 
    if (_thread.joinable()) { 
     _thread.join(); 
    } 
}; 

std::thread _thread; 
std::unique_ptr<ParallelTask> _task; 
}; 

int main() 
{ 
    TaskManager taskManager; 
    taskManager.startTask(); 

    // Do other stuff 

    taskManager.stopTask(); 
} 

また、私はLinuxベースのOSで動作しています。私はさらにGLibよりもpthreadベースのソリューションを好むだろう。しかし、他に解決策がない場合は、喜んでGLib提案を受け取ります。ありがとう!

答えて

0

私のニーズに合わせて、g_main_loop_runの代わりにg_main_context_iterationを使用できると判断しました。これにより、私自身のwhileループ内のすべてのGLibメインループイベントを処理することができます。これにより、std::condition_variable,std::mutexstd::shared_ptrなどのさまざまなstdスレッド・ユーティリティを柔軟に使用できます。あなたが原因あなたが `g_main_context_iterationを()`呼び出しを停止する直前にあっエンキューされることに `GMainContext`キューに立ち往生イベントに注意する必要がありますけれども、はい

#include <iostream> 
#include <string> 
#include <thread> 
#include <atomic> 
#include <chrono> 

#include <glib.h> 

using namespace std::chrono_literals; 

void concurrentTask(std::atomic_bool& process) 
{ 
    std::cout << "Beginning processing\n"; 

    GMainContext *context = g_main_context_default(); 

    // Register signals, etc... 

    while (process == true) 
    { 
     g_main_context_iteration(context, true); 
    } 

    g_main_context_unref(context); 
} 

int main() 
{ 
    std::atomic_bool process(true); 

    std::thread task(concurrentTask, std::ref(process)); 

    std::this_thread::sleep_for(2s); 
    process = false; 
    task.join(); 
    std::cout << "Processing complete\n"; 
} 
+0

g_main_context_iterationを使用する方法の例。 –

関連する問題