0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WindowsでもLinuxでも使えるスレッド

Posted at

以前は、Windowsでは _beginthreadex() 、Linuxでは pthread_create() を利用していました。
共通化出来ない上、C++のクラス内でスレッドを起こす場合は、staticのラッパー関数からスレッド本体の関数を呼ぶ必要があり面倒でした。
その後、C++11で追加されたstd::threadを使えば、これらが解決出来ることを知り、以降はもっぱらこちらを利用しています。

使い方

使い方はシンプルです。 thread をインクルードして、スレッド関数のポインターを引数にしてstd::threadクラスのインスタンスを作成するだけでスレッドを起こすことが出来ます。
終了時はjoin()でスレッド関数の終了待ちをします。

実装例

具体的には以下のように活用しています。WindowsでもLinuxでもビルド可能です。
CTestクラス内でスレッドを起こして一定間隔で変数をインクリメントします。
範囲内で最大の素数を求めるテスト用関数を実行後、結果と共に、その間にスレッドでインクリメントした数を表示します。

test.cpp
//#include <windows.h>          // for windows
#include <stdio.h>
#include <unistd.h>             // for linux
#include <string.h>
#include <thread>


//------------------------------------------------ Thread class
class CTest1
{
public:
	CTest1();
	virtual ~CTest1();
    typedef struct {
        std::thread th;
        int nReqQuit;
        int nCnt;
    } tagClassParameter;
    tagClassParameter *CP;

private:
    void ThreadFunc(void);
};


CTest1::CTest1()
{
    CP = new tagClassParameter;
    memset(CP, 0, sizeof(tagClassParameter));

    printf("start thread\n");
    (CP->th) = std::thread(&CTest1::ThreadFunc, this);
}


CTest1::~CTest1()
{
    (CP->nReqQuit) = 1;
    (CP->th.join)();

    printf("stop thread\n");
}


void CTest1::ThreadFunc(void)
{
    while((CP->nReqQuit)==0) {
        (CP->nCnt) ++;
        usleep(1000);               // for linux
        //Sleep(1);                   // for windows
    }
    (CP->nReqQuit) = 0;
}


//------------------------------------------------ test calculation
int CalcPrime(int nMax)
{
    int nNum = 3;
    int nRet = 1;

    while(nNum<=nMax) {
        for(int nLoop=2; nLoop<nNum; nLoop++) {
            int nAcm = nNum / nLoop;
            nAcm *= nLoop;
            if(nAcm==nNum) {
                break;
            }
            if(nNum<=(nLoop+1)) {
                nRet = nNum;
            }
        }
        nNum ++;
    }

    return(nRet);
}


//------------------------------------------------ main function
int main(int argc, char *argv[])
{
    CTest1 *ctp = new CTest1;

    int nAns = CalcPrime(100000);
    printf("nAns=%d  nCnt=%d\n", nAns, (ctp->CP->nCnt));

    delete ctp;

    return(0);
}

実行例

筆者の年代物のポンコツPCにて、最適化を指定しないビルドと実行結果はこちらです。

$ g++ -o test test.cpp 
$ ./test 
start thread
nAns=99991  nCnt=1351
stop thread

最適化を指定すると多少速くなります。

$ g++ -O2 -o test test.cpp
$ ./test 
start thread
nAns=99991  nCnt=983
stop thread
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?