Windowsでスレッドを作る

スレッドは高速化のためだが、結構デバッグが面倒なので使うときはシンプルな手法を選択したい。
また、スレッドは高速化のためだけでなく何らかの待機がある場合に使うこともある。今回はそれだ。ReadFile関数で呼び込むデータがない場合にデータが来るまでの間が止まっているような状態になる(そのプロセスだけ)。
main.c--------------------------------------------
#include <stdio.h>
#include <windows.h>
#include <process.h>

void th (void *);

int
main (int argc, int **argv)
{
  printf ("main ProcessID = x0%p\n", GetCurrentProcessId ());	//自分のプロセスIDを出力
  printf ("main ThreadID = x0%p\n", GetCurrentThreadId ());	//自分のスレッドIDを出力

  th ((void *) 20);		//通常の1スレッドでの実行確認用
  th ((void *) 20);		//通常の1スレッドでの実行確認用

  printf ("create thread\n");//別のスレッドを作る!!!!!!!!!!
  if (_beginthread (th, 0,	//スタックのサイズ 0でデフォルト
		    (void *) 50	//新しいスレッドが受け取る引数
      ) == (unsigned) -1)	//失敗する-1を返す
    fprintf (stderr, "ERR GetLastError=%d", GetLastError ());	//_beginthread()エラー時

  printf ("\nnext main th\n");//自分のスレッド
  th ((void *) 20);

  if ( argc != 1) Sleep (1000);	//第一引数に何かあったらSleep()を実行する
  return 0;			//成功したら0を返してmainを終了する
}

th.c-----------------------------------------
#include <stdio.h>
#include <windows.h>

void
th (void *count)		//スレッド関数
{
  int i, sum;

  printf ("%s ProcessID = x0%p main関数のプロセスと同じはず\n", __FILE__, GetCurrentProcessId ());	//自分のプロセスIDを出力
  printf ("%s ThreadID = x0%p main関数のプロセスとは違うこともある\n", __FILE__, GetCurrentThreadId ());	//自分のスレッドIDを出力
  sum = 0;
  for (i = 1; i <= (int) count; i++)
    {				//count分繰り返す
      printf ("i=%d ", i);
      fflush (stdout);
      sum += i;
    }
  printf ("\n ThreadID:x0%p sum= %d\n",GetCurrentThreadId(), sum);
  fflush (stdout);
  return;
}

スレッドを作るために別のファイルを用意する必要はない。単にファイルを分割したかっただけ。
コンパイルする。
C:\usr\lesson\opencv>cl main.c th.c
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

main.c
th.c
コードを生成中...
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.

/out:main.exe
main.obj
th.obj

実行してみる。
C:\usr\lesson\opencv>main
main ProcessID = x000001418
main ThreadID = x0000009FC
th.c ProcessID = x000001418 main関数のプロセスと同じはず
th.c ThreadID = x0000009FC main関数のプロセスとは違うこともある
i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10 i=11 i=12 i=13 i=14 i=15 i=16 i=17 i=18 i=19 i=20

ThreadID:x0000009FC sum= 210
th.c ProcessID = x000001418 main関数のプロセスと同じはず
th.c ThreadID = x0000009FC main関数のプロセスとは違うこともある
i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10 i=11 i=12 i=13 i=14 i=15 i=16 i=17 i=18 i=19 i=20

ThreadID:x0000009FC sum= 210
create thread

next main th
th.c ProcessID = x000001418 main関数のプロセスと同じはず
th.c ProcessID = x000001418 main関数のプロセスと同じはず
th.c ThreadID = x0000009FC main関数のプロセスとは違うこともある
th.c ThreadID = x0000000D0 main関数のプロセスとは違うこともある
i=1 i=1 i=2 i=3 i=4 i=2 i=5 i=6 i=7 i=8 i=9 i=10 i=11 i=12 i=13 i=14 i=15 i=16 i=3 i=4 i=1
7 i=5 i=18 i=19 i=6 i=7 i=8 i=20 i=9 i=10 i=11 i=21 i=12 i=22 i=13 i=23 i=14 i=24 i=15 i=1
6 i=25 i=26 i=17 i=27 i=18 i=28 i=29 i=19 i=30 i=20 i=31
ThreadID:x0000009FC sum= 210
i=32 i=33
C:\usr\lesson\opencv>
main.exeを実行する毎に出力結果は違う!!!!。
ThreadIDに注意して下さい。スレッドが違うとThreadIDの数値も違う。プロセスは1つなのでこれはすべて同じになる。
また、i=の数値が順番に大きくなってないところがあります。これは別のスレッドが出しているためです。
なお、新しく作った ThreadID = x0000000D0 の方は完全に処理が終わってないがmain関数の方が終了したので強制的に ThreadID = x0000000D0 の方も終了し、sum=の答えはありません。最後に見えるi=32 i=33は新しく作ったスレッドThreadID = x0000000D0の出力です。
main関数の終了を1秒遅らせるために適当な引数(ここではkkkk)を渡します。

C:\usr\lesson\opencv>main kkkk
main ProcessID = x0000015CC
main ThreadID = x000000594
th.c ProcessID = x0000015CC main関数のプロセスと同じはず
th.c ThreadID = x000000594 main関数のプロセスとは違うこともある
i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10 i=11 i=12 i=13 i=14 i=15 i=16 i=17 i=18 i=19 i=20

ThreadID:x000000594 sum= 210
th.c ProcessID = x0000015CC main関数のプロセスと同じはず
th.c ThreadID = x000000594 main関数のプロセスとは違うこともある
i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10 i=11 i=12 i=13 i=14 i=15 i=16 i=17 i=18 i=19 i=20

ThreadID:x000000594 sum= 210
create thread

next main th
th.c ProcessID = x0000015CC main関数のプロセスと同じはず
th.c ProcessID = x0000015CC main関数のプロセスと同じはず
th.c ThreadID = x000000594 main関数のプロセスとは違うこともある
th.c ThreadID = x00000179C main関数のプロセスとは違うこともある
i=1 i=1 i=2 i=2 i=3 i=3 i=4 i=4 i=5 i=5 i=6 i=6 i=7 i=7 i=8 i=8 i=9 i=9 i=10 i=10 i=11 i=1
1 i=12 i=12 i=13 i=14 i=15 i=13 i=16 i=17 i=18 i=19 i=20 i=21 i=14 i=22 i=23 i=24 i=15 i=1
6 i=25 i=17 i=26 i=18 i=27 i=19 i=28 i=29 i=20 i=30 i=31
ThreadID:x000000594 sum= 210
i=32 i=33 i=34 i=35 i=36 i=37 i=38 i=39 i=40 i=41 i=42 i=43 i=44 i=45 i=46 i=47 i=48 i=49
i=50
ThreadID:x00000179C sum= 1275

C:\usr\lesson\opencv>
最後のsum=は作ったスレッド側での計算結果です。main関数側のスレッドでsum=210の答えが出た後はi=32 i=33..のようにスレッドが1つなのでi=数値の値は順番に大きくなっている。
main.exeを実行する毎に出力結果は違う!!!!。
名前:
コメント:
「今日の訪問数: -
「昨日の訪問数: -
「今までの訪問数: -
最終更新:2012年10月02日 00:08
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。