cvl-robot's diary

研究ノート メモメモ https://github.com/dotchang/

大きなデータをネットワーク送信する間、他の処理が停止しないように、Windows用マルチスレッドを使えるようにする準備

マルチスレッド用ライブラリは、沢山ありますがposix環境ならpthreadが一般的です。Windows用にビルドされたpthreadライブラリも配布されていますので、一般的にはそれを使うのが良いと思います。

ただ今は、KinectFusionColorBasicsをマルチスレッド対応にしたいと考えていますので、わざわざPthreadに対応させるのも面倒です。WindowsAPIを利用して出来るだけ簡単にマルチスレッドを使う方法を調べると、下記のページでスマートな方法が紹介されていました。

http://bleis-tift.hatenablog.com/entry/20060315/1146910164

紹介されているソースコードをコピーペーストしてThread.hファイルを作り、

Thread.h

class Thread {
public:
    virtual ~Thread() {}
    void start();
    virtual void run() = 0;
private:
    static unsigned __stdcall run_(void*);
};

void Thread::start() {
    // thisポインタをreinterpret_castしてrun_に渡す
    _beginthreadex(0, 0, run_, reinterpret_cast<void*>(this), 0, 0);
}

unsigned __stdcall Thread::run_(void* that) {
    // ポインタを戻す
    Thread* thread = reinterpret_cast<Thread*>(that);
    thread->run();
    _endthreadex(0);
    return 0;
}

(引用)

#pragma once

#include <windows.h>

#include <process.h>

の三行を頭に加えてソースコードと同じ場所に置いてください。

マルチスレッドに対応させたいクラスの基底クラスとしてThreadを置いて、run関数を定義して、start関数でマルチスレッド実行します。

class CKinectFusionColorBasics_OCV : public Thread

自分でやるべきことは、

void run(){

// マルチスレッドで実行させたい中身

}

を書くだけですね。QtのQThreadなども同じ使い方です。

特定のデータ処理中に別のスレッドがそのデータを書き換えるとおかしなことがおきてしまいます。別のスレッドからのデータの書き換えを保護する方法としてMutexの利用が一般的です。Windows版のMutexの使い方は、

http://onishi-lab.jp/programming/thread_win.html

にサンプル付で紹介されています。

HANDLE hMutex; //ミューテックスのハンドル

WaitForSingleObject(hMutex,INFINITE); //mutex 間は他のスレッドから変数を変更できない
//保護したい処理

ReleaseMutex(hMutex);

で良いようです。posixと関数名が違うぐらいで使い方は同じですね。