ページ 11

文字を書き込めない

Posted: 2010年7月21日(水) 17:21
by shiro4ao
メインのスレッドでひたすらbufに"B"を書き込む
サブのスレッドでひたすらbufに"A"を書き込み出力する

ということを1000回繰り返しました。
しかし、一回も"B"が書き込まれることなく終了してしまいました。

この方法で一回でいいからBと出力して欲しいのですが可能でしょうか?

===================ここから===============================
#include <windows.h>
#include <stdio.h>

char buf[1024];
int j=1000;

DWORD WINAPI SubThread(LPVOID vdParam) {
int i=0;
while (i<j) {
strcpy(buf,"A");
printf(buf);
i++;
}
ExitThread(TRUE);
}

int main(void){
int i=0;
char a[1024];
CreateThread(NULL , 0 , SubThread , NULL , 0 ,NULL);
while (i<j) {
strcpy(buf,"\nB\n"); //探しやすいようにBの前後に改行を入れました
i++;
}
gets(a); //結果をコンソール上で見るために終了させないようにするためです
return 0;
}

====================ここまで============================

Re:文字を書き込めない

Posted: 2010年7月21日(水) 17:40
by シエル
まず、一つの変数に同時に複数のスレッドから書き込みを行うのは
やめたほうがいいと思います。

どうしてもBを出力したければ、
下記のようにサブスレッドでAをコピった後に、スリープを入れたらいいんじゃないですかね。

strcpy(buf,"A");

Sleep(1);

printf(buf);


こうすれば、何回かに一回はBが表示されるんではないでしょうか。

画像

Re:文字を書き込めない

Posted: 2010年7月21日(水) 17:55
by shiro4ao
ありがとうございます。
複数のスレッドから書き込みが上手くいかないということを実感するために
なんとなく書いたプログラムなのであんまり気にしなくていいと思います。
(ただ、うまく「不具合」が起こってくれないので困っているのです・・・)

Slepp(100)くらいにしていれてみたのですが、全く変化なしでした。
最初の一回だけ、Bが出力されて、それ以降はAが連続で出てきます。
確認したら、サブスレッドが書き込んでいるときは、メインスレッドの処理は
させてもらえていないようでした。

「複数のスレッドから書き込みは危険な場合があるから避けましょう」

という程度の発生率でしかないのでしょうか?

Re:文字を書き込めない

Posted: 2010年7月21日(水) 18:13
by Poco
>(ただ、うまく「不具合」が起こってくれないので困っているのです・・・)

マルチスレッドに起因する問題は、タイミング問題です。
現象が発生しないのは、試行時間が短いか、試行回数が少ないからです。
1000回ループではなく、100万回ループにし、プログラム自体を100回くらい動かしてください。
んで、表示する文字列も長くしてください。
A、Bともに100文字程度にしてみてどうですか?

>「複数のスレッドから書き込みは危険な場合があるから避けましょう」
>という程度の発生率でしかないのでしょうか?


問題なのは発生率の高さではありません。
発生すること自体が問題なのです。

>「複数のスレッドから書き込みは危険な場合があるから避けましょう」

と書かれていますが、なぜ危険なのか理解していますか?

Re:文字を書き込めない

Posted: 2010年7月21日(水) 18:30
by shiro4ao
>んで、表示する文字列も長くしてください。
>A、Bともに100文字程度にしてみてどうですか?

Aを長くしたら、途中でBが出てきました。

実際に使う場合は長い文字列でも当然なのでたしかに危険だと思いました・・・・
書き込み内容が意図せずに変わっていたら、発見しにくいバグになるかもしれないので
実際に使う際は注意したいと思います。

シエルさん、ぽこさんありがとうございました。
これにて解決とさせていただきます。