マルチスレッド処理のメモ
USBカメラやipカメラの映像を取得するプログラムを作成中。いずれ全体を載せたいと思うけど、とりあえずマルチスレッド処理の所だけ。
サンプル.cpp
#include <thread>
class _USBCAM
{
public:
//ここらは本稿では使わない
cv::VideoCapture capture;
int _show(); //登録してあるハンドルに表示
int _show2(); //opencvのウィンドウに表示
int _show(HWND hWnd, int nIDDlgItem);
int _close();
int _init(int _cam_num, int _width, int _height, int _fps, HWND hWnd, int nIDDlgItem);//スレッド開始に必要な引数は、念のためキック前にあらかじめ渡しておく。
//ここからスレッド関連
int _show_thread(); //登録してあるハンドルに表示
int _show_thread_sub(); //登録してあるハンドルに表示
std::thread *_thd; //マルチスレッドをしたい関数のアドレスを格納するスレッドクラスのポインタ
};
//スレッドにキックをかける関数。ダイアログボックスのボタン。
void CUSBCamMFC3Dlg::_OnBnClickedButtonU(int _cn, int _id, int _idcw, int _idch, int _idcf)
{
//描画関係の初期化
_uc[_cn]._init(_cn, _w, _h, _f, m_hWnd, _id); //_PicContId
//マルチスレッド処理↓ デバッグモードだと実行時エラーが出るかも。
_uc[_cn]._show_thread();
}
int _USBCAM::_show_thread()
{
//スレッドに関数を登録
_thd = new std::thread([this]() {this->_show_thread_sub(); });
return 0;
}
//マルチスレッド化する描画する関数
//whileでひたすらルーチン処理するが、他の処理も進む
int _USBCAM::_show_thread_sub()
{
int _ret=0;
while (_cam_on)
{
_ret = DrawPicToHDC(_getimg(), _hWnd, _nIDDlgItem, true /* =true*/);
}
return _ret;
}
何のこたあない、マルチ処理したい部分を関数化してそのアドレスをstd::threadクラスに渡せばよい。型キャストが難しくなったなあ。昔は全部(void*)()でキャストしてた記憶が。ていうか自作していたっけ。
threadクラスにはjoin()とかスレッドを管理する関数とかあるので詳しくは下記のリンク先へ。それにしても完全にスレッドをkillする関数が無いなあ。まあいいけど。変数にアンダーバーを使うのは癖なので気にしないように。
バッチファイルでマルチスレッド
ちなみにマルチスレッドプログラミングはバッチファイルでも出来る。
↓こんな感じのバッチファイルを作る。
sample.bat
@echo off
echo dir>_sub.bat
echo ffmpeg -i %%1.avi %%1.avi>>_sub.bat
rem マルチスレッド処理したいコマンドをechoで_sub.batに書いていく。
rem %と\は二重化して記述すること
start _sub.bat hoge1
start _sub.bat hoge2
start _sub.bat hoge3
バッチファイルの中でサブルーチンとなる別のバッチファイルを作ってstartコマンドでキックする。簡単だね。これで動画変換が同時進行していく。もちろんハードの制約はあるがそれはOSが処理してくれる。C++やC#のマルチスレッド処理もバッチと原理は同じ。仕組みが分かっていれば何のこたあない。