現在、下記のようなプログラムを作成しています。
内容は、メッセージキューを受信するスレッドを生成するというイメージです。
処理内容は下記のようになります。
(1)メッセージキューの生成
(2)スレッド生成(メッセージキュー受信側)
(3)スレッド停止
(4)メッセージキューの削除
しかし、(3)のスレッド停止を実施しても、(4)のメッセージキューの削除以降にて、msgrcvのエラーが出力されてしまいます。
スレッド停止を行ったことから、TestThreadは動作しなくなり、(4)のメッセージキューの削除にて、エラーともならずに終了することを望んでりますが、上手くいきません。
下記に作成しているプログラムを記載いたします。
正常終了をするには何がいけないのでしょうか?
ご教授宜しくお願い致します。
[test.cc]
----------------------------------------------------------------
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
// メソッドポインタ定義
typedef void (*testT);
// スレッドID
pthread_t threadId;
// メッセージキュー識別子
int msqId;
// 送受信するメッセージ
struct msgbuf{
long int type;
char data[BUFSIZ];
};
// テストスレッド
void TestThread()
{
// メッセージ
struct msgbuf message;
while( 1 )
{
printf("### TEST ###\n");
printf("msq start\n");
// 受信
if( msgrcv( msqId, &message, BUFSIZ, 0, 0 ) == -1)
{
printf("ERR! msgrcv errno[%d]\n", errno);
continue;
}
printf("msq ed\n");
sleep(1);
}
return;
}
// メイン
int main(int argc, char *argv[])
{
// メッセージキュー識別子退避変数
int testMsqid;
// スレッド操作リターン値
int status;
// スレッドa用のパラメータ
pthread_t thread_test;
printf("### TEST START ###\n");
// メッセージキューの作成
if( (testMsqid = msgget((key_t)1111, 0666 | IPC_CREAT)) == -1 )
{
printf("ERR! CREATE bkMsqId[%d]\n", testMsqid);
return 1;
}
// メッセージキュー識別子を共通変数に設定
msqId = testMsqid;
printf("msgget OK\n");
sleep(5);
// スレッドを生成
status = pthread_create(&thread_test, NULL, (void*(*)(void*))TestThread, (void*)NULL);
if(status!=0)
{
printf("pthread_create ng\n");
return 1;
}
printf("pthread_create OK\n");
sleep(5);
// スレッド停止
status = pthread_cancel(thread_test);
// スレッド停止結果
if ( status != 0 )
{
printf("pthread_cancel ng\n");
return 1;
}
printf("pthread_cancel OK\n");
sleep(5);
// メッセージキューの削除
if ( msgctl( msqId, IPC_RMID, NULL) == -1 )
{
printf("msqId[%d] errno[%d]\n", msqId, errno);
return 1;
}
printf("msgctl OK\n");
sleep(5);
printf("### TEST E N D ###\n");
return 0;
}
----------------------------------------------------------------
No.1ベストアンサー
- 回答日時:
1.スレッドのcanceltypeが
PTHREAD_CANCEL_DEFERRED(デフォルト値)
の場合、そのスレッドは次のcancellation pointまで止まりません。
2. IPCのmsgrcv()が 安全な cancellation point になるかどうかは怪しいです。(実装依存で結果不定が正解だと思います。)
対策としては、明示的に cancellation point
~pthread_testcancel()など~
を埋め込むのが確実でしょう。
ご教授ありがとうございます。
msgrcvはキャンセルポイントであると思っておりました。
明示的にキャンセルポイントを埋め込むと、可能であるのですね。
逆に、スレッドのcanceltypeが
PTHREAD_CANCEL_ASYNCHRONOUS
(取り消し要求が届くと直ちに呼び出しスレッドを取り消す)
であると、直ちに取り消すということになるのですよね?
2種類の方法があると思われますので、両方とも試してみたいと思います。
大変有り難う御座いました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
あなたの「必」の書き順を教えてください
ふだん、どういう書き順で「必」を書いていますか? みなさんの色んな書き順を知りたいです。 画像のA~Eを使って教えてください。
-
これ何て呼びますか
あなたのお住いの地域で、これ、何て呼びますか?
-
メモのコツを教えてください!
メモを取るのが苦手です。 急いでメモすると内容がごちゃごちゃになってしまったり、ひどいときには全く読めない時もあります。
-
この人頭いいなと思ったエピソード
一緒にいたときに「この人頭いいな」と思ったエピソードを教えてください
-
高校三年生の合唱祭で何を歌いましたか?
大人になると大人数で合唱する機会ってないですよね。 思い出すと、高校三年生の合唱祭が最後でした。 そこで、みんなの思い出の合唱曲を知りたい!
-
マルチスレッド間でデータ交換をする方法
C言語・C++・C#
-
メッセージキューのスレッド間通信
UNIX・Linux
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
c言語でAからZまでを表示する...
-
10個出力で改行したいのですが...
-
printf で二進表示を行いたい。
-
【C言語教えてください】sin波...
-
C言語初心者です。次の問題で質...
-
C言語で、printfのような関数の...
-
コマンドプロンプトがすぐ消える
-
関数を使ったプログラミング
-
プログラミング教えてください
-
C言語【おみくじプログラム】
-
なぜgccはstdio.hをインクルー...
-
cshの文字列操作(0埋め)
-
%P と %X の違い
-
unsigned int型について
-
勝率をプログラムに
-
printfでSegmentation fault
-
二つの整数値の大小比較
-
コマンドラインに出力した文字...
-
ホームページをC言語で作りたい...
-
Cプログラミングのアルゴリズム...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
CTRL+Dでループを抜けるには
-
printf で二進表示を行いたい。
-
【C言語教えてください】sin波...
-
コンパイルエラーについて
-
c言語でAからZまでを表示する...
-
4の倍数を論理演算で表す。。
-
台形の面積を求めるプログラム
-
8人分のテストの点数を入力し、...
-
コマンドラインに出力した文字...
-
switch分のケースを範囲数?に...
-
(C言語)めちゃくちゃな値にな...
-
テキストカーソル位置の取得
-
strcmp
-
defineで定数が置き換えられな...
-
WM_CLOSEで閉じれないウィンド...
-
%P と %X の違い
-
cshの文字列操作(0埋め)
-
円の面積を求めるプログラミン...
-
printfの出力内の文字をdefine...
おすすめ情報