![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
現在、下記のようなプログラムを作成しています。
内容は、メッセージキューを受信するスレッドを生成するというイメージです。
処理内容は下記のようになります。
(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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
10個出力で改行したいのですが...
-
strcmp
-
error C2143: 構文エラー : ';'...
-
スレッドとメッセージキューに...
-
C言語 タイマーのソースについて
-
C言語プログラミング
-
Cプログラムについて
-
インクリメント演算子をprintf...
-
コマンドラインに出力した文字...
-
C言語の数値入力
-
コンパイルエラーについて
-
c言語でAからZまでを表示する...
-
hit&bolwのプログラミングがで...
-
プログラミング言語C
-
C言語のヘッダーファイルの作成...
-
C++ 二次関数の重解、虚数解が...
-
unsigned int型について
-
scanfで正しい値を入力できない
-
int型 00 を表示するのに0とな...
-
関数について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
【C言語教えてください】sin波...
-
printf で二進表示を行いたい。
-
c言語でAからZまでを表示する...
-
コマンドラインに出力した文字...
-
strcmp
-
4の倍数を論理演算で表す。。
-
C言語での、年複利の計算方法...
-
C言語 プログラミング
-
scanfに文字が入力されたときに...
-
hit&bolwのプログラミングがで...
-
%P と %X の違い
-
unsigned int型について
-
printf( " %2d", p * q );
-
cshの文字列操作(0埋め)
-
改行について 1行に何個かづ...
-
8人分のテストの点数を入力し、...
-
入力したお金の金額からお札の...
-
三角形の判別
-
テキストカーソル位置の取得
おすすめ情報