スレッド間のデータのやりとりについて
スレッド間のデータのやりとりについて
はじめまして。
今、スレッドについて勉強しています。そこでスレッド間のメッセージのやりとりの方法がいまいちよくわかりません…
PostThreadMessage()でメッセージの送信、GetMessage()でメッセージの受信でよろしいのでしょうか?
また、PostThreadMessage()の引数が何をいれたらいぃのかわかりません。
ちなみに送信したい内容はchar型のstrというデータで送信先のスレッド名はanswer_threadです。
詳しい人がいたらご教授をお願いします。また、他の方法でデータのやりとりをしている人がいたら教えてください。
今、スレッドについて勉強しています。そこでスレッド間のメッセージのやりとりの方法がいまいちよくわかりません…
PostThreadMessage()でメッセージの送信、GetMessage()でメッセージの受信でよろしいのでしょうか?
また、PostThreadMessage()の引数が何をいれたらいぃのかわかりません。
ちなみに送信したい内容はchar型のstrというデータで送信先のスレッド名はanswer_threadです。
詳しい人がいたらご教授をお願いします。また、他の方法でデータのやりとりをしている人がいたら教えてください。
Re:スレッド間のデータのやりとりについて
ポスト先のスレッドに予めメッセージキューを作成してあるなら、それでも。
普通はスレッド間のデータ共有にはクリティカルセクションとか、ミューテックスとか、セマフォなど同期オブジェクトを状況に合わせて使います。
>また、PostThreadMessage()の引数が何をいれたらいぃのかわかりません
送る型は char型の変数 strなら、1バイトなのでさくっと
PostThreadMessage(ポスト先スレッドID,メッセージID, (WPARAM)str, 0)
なかんじで良いんじゃないでしょうか。
あとは MSDNとかは Googleで調べればいろいろもっと詳しいことがわかるかと思います。
普通はスレッド間のデータ共有にはクリティカルセクションとか、ミューテックスとか、セマフォなど同期オブジェクトを状況に合わせて使います。
>また、PostThreadMessage()の引数が何をいれたらいぃのかわかりません
送る型は char型の変数 strなら、1バイトなのでさくっと
PostThreadMessage(ポスト先スレッドID,メッセージID, (WPARAM)str, 0)
なかんじで良いんじゃないでしょうか。
あとは MSDNとかは Googleで調べればいろいろもっと詳しいことがわかるかと思います。
Re:スレッド間のデータのやりとりについて
Justyさん、ご回答いただきありがとうございました。
PostThreadMessage()の引数はそんな内容だったんですね。
ありがとうございました。
ところで、PostThreadMessage()が送信したメッセージが、スレッドで受け取るにはGetMessage()でもよいと仰っていましたが、以下のような使い方でよろしいのでしょうか。
MSG msg;
GetMessage(&msg, NULL, 0, 0);
この場合、GetMessage()の引数であるmsgにstrの内容が格納されるのでしょうか?
PostThreadMessage()の引数はそんな内容だったんですね。
ありがとうございました。
ところで、PostThreadMessage()が送信したメッセージが、スレッドで受け取るにはGetMessage()でもよいと仰っていましたが、以下のような使い方でよろしいのでしょうか。
MSG msg;
GetMessage(&msg, NULL, 0, 0);
この場合、GetMessage()の引数であるmsgにstrの内容が格納されるのでしょうか?
Re:スレッド間のデータのやりとりについて
>GetMessage()でもよいと仰っていましたが、以下のような使い方でよろしいのでしょうか。
それでいいと思います。
>この場合、GetMessage()の引数であるmsgにstrの内容が格納されるのでしょうか?
MSDNか何かのリファレンスは読みましたか?
PostThreadMessage()側でどう設定したかにもよりますが、msg構造体の中のメンバ変数に格納されます。
以下はサンプルです(エラー処理とか何もしてないので注意)。
それでいいと思います。
>この場合、GetMessage()の引数であるmsgにstrの内容が格納されるのでしょうか?
MSDNか何かのリファレンスは読みましたか?
PostThreadMessage()側でどう設定したかにもよりますが、msg構造体の中のメンバ変数に格納されます。
以下はサンプルです(エラー処理とか何もしてないので注意)。
[color=#d0d0ff" face="monospace]#include <windows.h>
#include <stdio.h>
DWORD MainThreadID;
DWORD WINAPI DoThread(LPVOID x)
{
char c = 'A';
do
{
PostThreadMessage(MainThreadID, WM_APP, (WPARAM)c, 0);
Sleep(100);
} while(isgraph(++c));
PostThreadMessage(MainThreadID, WM_QUIT, 0, 0);
return 0;
}
int main(void)
{
int count = 0;
MSG msg;
MainThreadID = GetCurrentThreadId();
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DoThread, NULL, 0, NULL);
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
if(msg.message == WM_APP)
printf("[%d] Receive %c\n", ++count, (char)msg.wParam);
}
return 0;
}[/color]
Re:スレッド間のデータのやりとりについて
Justyさん、回答ありがとうございます。
MSDNとかのリファレンスはいろいろ読んでるんですが、いまいち理解出来ないところが多くて‥
今回はサンプルプログラムまで載せてくれて、本当にありがとうございました。
あとは、なんとか理解してやってみます。
ご回答ほんとうにありがとうございました。
MSDNとかのリファレンスはいろいろ読んでるんですが、いまいち理解出来ないところが多くて‥
今回はサンプルプログラムまで載せてくれて、本当にありがとうございました。
あとは、なんとか理解してやってみます。
ご回答ほんとうにありがとうございました。
Re:スレッド間のデータのやりとりについて
わからないことが出てきたので、また質問させていただきます。
今、main()のスレッドで、char regstrに格納されたデータをans_thread()スレッドに送りたいんですが、
ポストの書式は、PostThreadMessage(at_id,WM_APP,(WPARAM)regstr,0);でよろしいのでしょうか?
また、受け取る側のスレッド(ans_thread())は、MSG msg;を宣言してGetMessage(&msg,NULL,0,0);でよろしいのでしょうか?
ちなみに、受け取ったデータをsend()で送りたいんですが、send(sock,msg.wParam,strlen(msg.wParam), 0);なかたちでよろしいのでしょうか…?このようにすると、「2 番目の引数を 'WPARAM' から 'const char *' に変換できません。」というエラーが発生します。
MSDNのリファレンスを見たのですがやはり理解に苦しみまして…
わかる人がいたらお願いします。
今、main()のスレッドで、char regstrに格納されたデータをans_thread()スレッドに送りたいんですが、
ポストの書式は、PostThreadMessage(at_id,WM_APP,(WPARAM)regstr,0);でよろしいのでしょうか?
また、受け取る側のスレッド(ans_thread())は、MSG msg;を宣言してGetMessage(&msg,NULL,0,0);でよろしいのでしょうか?
ちなみに、受け取ったデータをsend()で送りたいんですが、send(sock,msg.wParam,strlen(msg.wParam), 0);なかたちでよろしいのでしょうか…?このようにすると、「2 番目の引数を 'WPARAM' から 'const char *' に変換できません。」というエラーが発生します。
MSDNのリファレンスを見たのですがやはり理解に苦しみまして…
わかる人がいたらお願いします。
Re:スレッド間のデータのやりとりについて
> strlen(msg.wParam)
とありますが、msg.wParamがWPARAM型であるのに対して、strlenの引数はchar*です。
従ってキャストする必要あります。
が、この場合msg.wParamはchar型のregstrですよね?
それなら文字列ではなくsizeof(char)=1byte固定なので、
send(sock,msg.wParam,1, 0);
でいいと思います。
# 上のほうを見ていて気になったのですが、
# 実はcharじゃなくてchar*(文字列)のやり取りをするつもりでということはないですよね?
とありますが、msg.wParamがWPARAM型であるのに対して、strlenの引数はchar*です。
従ってキャストする必要あります。
が、この場合msg.wParamはchar型のregstrですよね?
それなら文字列ではなくsizeof(char)=1byte固定なので、
send(sock,msg.wParam,1, 0);
でいいと思います。
# 上のほうを見ていて気になったのですが、
# 実はcharじゃなくてchar*(文字列)のやり取りをするつもりでということはないですよね?
Re:スレッド間のデータのやりとりについて
@masさん
>実はcharじゃなくてchar*(文字列)のやり取りをするつもり~
strlenを見て私もそんな気がしてきました。
@satoshiさん
>ポストの書式は、PostThreadMessage(at_id,WM_APP,(WPARAM)regstr,0);でよろしいのでしょうか?
regstrの型が char(1バイト)ならOK。
ただ WM_APPのIDに関しては 0x8000~0xBFFFの間で自由にIDを設定できるので、WM_APPのまま使わないで、自前で別定義を用意した方がいいでしょう(http://yokohama.cool.ne.jp/chokuto/uraw ... _USER.html)。
>受け取る側のスレッド(ans_thread())は~でよろしいのでしょうか?
多分それでいいと思いますが、実際のところはその周辺をどう書いているのかにも依存します。
# もし万が一、送りたい型が charではなく char*ないしは char[/url]であるなら。
PostThreadMessage()では WPARAMと LPARAMの2つのパラメータしか送れません。
つまり合わせて最大8バイトまでです。
文字列を送りたいのであれば、ちょっと工夫が必要になります。
>実はcharじゃなくてchar*(文字列)のやり取りをするつもり~
strlenを見て私もそんな気がしてきました。
@satoshiさん
>ポストの書式は、PostThreadMessage(at_id,WM_APP,(WPARAM)regstr,0);でよろしいのでしょうか?
regstrの型が char(1バイト)ならOK。
ただ WM_APPのIDに関しては 0x8000~0xBFFFの間で自由にIDを設定できるので、WM_APPのまま使わないで、自前で別定義を用意した方がいいでしょう(http://yokohama.cool.ne.jp/chokuto/uraw ... _USER.html)。
>受け取る側のスレッド(ans_thread())は~でよろしいのでしょうか?
多分それでいいと思いますが、実際のところはその周辺をどう書いているのかにも依存します。
# もし万が一、送りたい型が charではなく char*ないしは char[/url]であるなら。
PostThreadMessage()では WPARAMと LPARAMの2つのパラメータしか送れません。
つまり合わせて最大8バイトまでです。
文字列を送りたいのであれば、ちょっと工夫が必要になります。
Re:スレッド間のデータのやりとりについて
masさん、Justyさん回答していただきありがとうございます。
>masさん
>実はcharじゃなくてchar*(文字列)のやり取りをするつもりでということはないですよね?
申し訳ありません。実はchar*でのやり取りでした。
>Justyさん
>もし万が一、送りたい型が charではなく char*ないしは char[/url]であるなら。
PostThreadMessage()では WPARAMと LPARAMの2つのパラメータしか送れません。
つまり合わせて最大8バイトまでです。
最大8バイトまでなんですか!?送るのは結構長い文字列なんですよね…
その場合は8バイトづつに分けて送るという感じなるんですか?
無知で申し訳ありません。
>masさん
>実はcharじゃなくてchar*(文字列)のやり取りをするつもりでということはないですよね?
申し訳ありません。実はchar*でのやり取りでした。
>Justyさん
>もし万が一、送りたい型が charではなく char*ないしは char[/url]であるなら。
PostThreadMessage()では WPARAMと LPARAMの2つのパラメータしか送れません。
つまり合わせて最大8バイトまでです。
最大8バイトまでなんですか!?送るのは結構長い文字列なんですよね…
その場合は8バイトづつに分けて送るという感じなるんですか?
無知で申し訳ありません。
Re:スレッド間のデータのやりとりについて
>>最大8バイトまでなんですか!?送るのは結構長い文字列なんですよね…
ぱっと思いついたのを少しサンプルを改造して作ってみました。
動作を追ってみてください。
この方法なら mallocできる限り多少文字列が長くても問題はないですが、決してメッセージの取りこぼしがあってはいけません。
あった場合、メモリリークになります。
この程度の文字列なら無理にメッセージで送らなくてもクリティカルセクション・セマフォとかの同期オブジェクトを使った方がいいかと思います。
ぱっと思いついたのを少しサンプルを改造して作ってみました。
動作を追ってみてください。
[color=#d0d0ff" face="monospace]#include <windows.h>
#include <stdio.h>
#include <time.h>
static DWORD MainThreadID;
#define WM_APP_STRING (WM_APP + 10)
DWORD WINAPI DoThread(LPVOID x)
{
static const char * const str_tbl[/url]
= { "ABCDEFG", "abcdefg", "12345", "67890", "3.1415926535" };
unsigned counter = 50;
do
{
unsigned index = rand() % 5;
char *buff = (char*)malloc(5 + strlen(str_tbl[index]) + 1);
sprintf(buff, "%2d : %s", counter, str_tbl[index]);
PostThreadMessage(MainThreadID, WM_APP_STRING, 0, (LPARAM)buff);
Sleep(100);
} while(--counter);
PostThreadMessage(MainThreadID, WM_QUIT, 0, 0);
return 0;
}
int main(void)
{
int count = 0;
MSG msg;
MainThreadID = GetCurrentThreadId();
srand((unsigned)time(NULL));
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DoThread, NULL, 0, NULL);
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
if(msg.message == WM_APP_STRING)
{
char *receive_str = (char*)msg.lParam;
printf("[%d] Receive %s\n", ++count, receive_str);
free(receive_str);
}
}
return 0;
}[/color]
Post側で mallocしたバッファに文字列を入れ、Post先で使い終わったら解放しています。この方法なら mallocできる限り多少文字列が長くても問題はないですが、決してメッセージの取りこぼしがあってはいけません。
あった場合、メモリリークになります。
この程度の文字列なら無理にメッセージで送らなくてもクリティカルセクション・セマフォとかの同期オブジェクトを使った方がいいかと思います。
Re:スレッド間のデータのやりとりについて
Justyさん、ありがとうございます。
サンプルまで載せていただきありがとうございます。
クリティカルセクションやセフォマとかでも出来るんですね。
勉強になります。そこらへんも調べてまた頑張ってみます。
ご回答ありがとうございました。
サンプルまで載せていただきありがとうございます。
クリティカルセクションやセフォマとかでも出来るんですね。
勉強になります。そこらへんも調べてまた頑張ってみます。
ご回答ありがとうございました。