• 締切済み

C++におけるスレッド制御に関して

C++初心者です。 スレッド制御の勉強をしておりますが、 なかなかうまくいきません。 下記のソースのようにスレッド生成をしておりますが、 スレッド用メソッドには、*を付けて使用するしか方法はないのでしょうか? pthread_createに渡す第3パラメータをメソッド名のみにして、呼ばれ元のメソッドの戻り値をvoid* ではなく、void のみで実施したいと思っておりますが、方法がわかりません。 大変申し訳ございませんが、ご教授よろしくお願いいたします。 ############################################################## # pthread_test.cc ############################################################## #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> /* * スレッドパラメータ格納用 */ typedef struct {  char printVal;  int interval; } ThreadParamT; // スレッドイニシャル関数 void *ThreadTest(void *arg) {  ThreadParamT *thread_test_param =(ThreadParamT*)arg;  while(1) {   fprintf(stderr,"%c", thread_test_param->printVal);   sleep(thread_test_param->interval);  }  return NULL; } int main(int argc,char *argv[]) {  int status;  // スレッドのパラメータ  pthread_t thread_test;  ThreadParamT thread_test_param;  thread_test_param.printVal = 'a';  thread_test_param.interval = 1;  // スレッドを生成  status=pthread_create(&thread_test, NULL, ThreadTest, &thread_test_param);  if(status!=0){   fprintf(stderr,"ERR! OUT!\n");   exit(1);  }  // 10s間待つ  sleep(10);  fprintf(stderr, "\n");  return 0; } ##############################################################

みんなの回答

回答No.2

> 既存メソッド数分のThreadTestが必要になるのかな?と思っております。 機械的に作るんじゃダメ? #include <iostream> /* たしざん */ struct arg_int_int {   int x;   int y; }; void add(arg_int_int* arg) {   std::cout << "add result = " << (arg->x + arg->y) << std::endl; } /* ぜったいち */ struct arg_int {   int value; }; void absolute(arg_int* arg) {   std::cout << "absolute result = " << ((arg->value > 0) ? arg->value : -arg->value) << std::endl; } /* なんちゃってスレッド生成 */ typedef void* (*thread_entry)(void*); void call(thread_entry entry, void* arg) {   (*entry)(arg); } /* 機械的にエントリを生成するマクロ */ #define ENTRY(FUNC) entry##FUNC #define define_ENTRY(FUNC,TYPE) \ void* ENTRY(FUNC)(void* arg) {\  FUNC((TYPE*)arg); \  return 0; \ } /* おためし */ /* add と absolute を作って呼ぶ */ define_ENTRY(add,arg_int_int); define_ENTRY(absolute,arg_int); int main() {  arg_int_int aii = { 1, 2 };  arg_int ai = { -3 };  call(ENTRY(add), &aii);  call(ENTRY(absolute), &ai); }

回答No.1

薄皮一枚かぶせるんじゃダメなんでしょか? void ActualEntry(ThreadParam* param) {  while(1) {   fprintf(stderr,"%c", param->printVal);   sleep(param->interval);  } } void *ThreadTest(void *arg) {  Actualentry((ThreadParamT*)arg);  return NULL; }

shin-emi
質問者

お礼

ご回答ありがとうございます。 なるほど~。参考になります。 スレッドの呼び先にワンクッション置くということですね。 実はやりたいことは、既に作成したプログラムをマルチスレッド化したのです。(作成済のプログラムというのは、ファイル操作や、メッセージキュー操作のプログラムとなります。) マルチスレッド化するとなると、既存のメソッドの戻り値をvoid*に変更しなくてはいけないのでは..??という懸念から、既存メソッドに触らずにスレッド化した意向です。 スレッド制御用に、メソッドをひとつ追加して(上記のmainに当たります。)、その制御メソッドにパラメータでスレッド用メソッド名?ポインタ?(上記でいうとThreadTestが既存メソッドになります)を渡すことで、pthread_createにパラメータで指定されたメソッドが起動されるといったことがやりたいのです。 epistemeさんからご教授頂いた方法であれば、既存メソッド数分のThreadTestが必要になるのかな?と思っております。

関連するQ&A

  • スレッドとメッセージキューに関して

    現在、下記のようなプログラムを作成しています。 内容は、メッセージキューを受信するスレッドを生成するというイメージです。 処理内容は下記のようになります。  (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; } ----------------------------------------------------------------

  • スレッドを2つ作って1秒ごとに2つのスレッドが数値を表示するプログラム

    スレッドを2つ作って1秒ごとに2つのスレッドが数値を表示するプログラムを作りたいのですがうまくいきません。 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/socket.h> #include<arpa/inet.h> #include<unistd.h> #include<pthread.h> void *threadMain(void *threadArgs); int main(void) { int i = 0; pthread_t threadID; for(i = 0;i < 2;i++){ pthread_create(&threadID,NULL,threadMain,(void *)NULL); } } void *threadMain(void *threadArgs) { int i = 0; while(1){ printf("%d\n",++i); sleep(1); } } 上記プログラムを実行すると1が2回表示されて終了してしまいます。 どこか間違えがあるのでしょうか。。

  • クラス内でのpthread_createに関して

    C言語初心者です。 下記のようなソースにて、クラス内でのスレッドを行うことが目的です。 しかし、下記のpthread_createにてコンパイルエラーとなります。 キャストエラーのようなのですが、キャスト方法がわかりません。 初歩的な質問で、大変申し訳御座いませんが、ご教授頂けませんでしょうか? ################################################################ #include <stdio.h> #include <pthread.h> // Testクラス class Test{ private: // スレッド処理 void testThread() { printf("### THREAD START ###\n"); return; } public: // スレッド開始 void threadStart() { // スレッド生成戻り値 int status; // スレッド pthread_t thread; // スレッド生成 status = pthread_create( &thread, NULL, (void*(*)(void*))testThread, NULL ); // スレッド生成結果 if ( status != 0 ) { printf("ERR!! pthread_create NG\n"); } return; } }; // メイン実行 int main(int argc, char *argv[]) { // Testクラスオブジェクト Test test; printf("### TEST START ###\n"); test.threadStart(); printf("### TEST E N D ###\n"); return 0; } ################################################################ 宜しくお願い致します。 以上です。

  • スレッドの作成について(pthread_create関数)

    以下のプログラムをLinuxで実行するとpthread_create関数の戻り値が『1』となり、errno変数には『4』が入ってしまいます。(どちらにも『0』が入っててほしい) 何がやりたいのかというと、子スレッドのプライオリティを優先指定にして、子スレッドが生成されることを確認したいだけなのですが。。。 (下のプログラムじゃきっと本質的には確認できたことにはならないとおもいますが。。。) 何故pthread_create関数の戻り値が『1』となり、errno変数には『4』が入ってしまうかわかる方、どなたかご教授願えませんでしょうか? -------------------------------ここから------------------------------- #include <pthread.h> #include <errno.h> void *test2( void * ); int main ( int argc, char **argv ) { int iThCreateRes=0; pthread_attr_t t_attr; int bRet=0; pthread_t szThreadHandle; errno = 0; pthread_attr_init( &t_attr ); pthread_attr_setdetachstate( &t_attr, PTHREAD_CREATE_JOINABLE ); pthread_attr_setschedpolicy( &t_attr,SCHED_RR ); pthread_attr_setinheritsched( &t_attr, PTHREAD_EXPLICIT_SCHED ); pthread_attr_setscope( &t_attr, PTHREAD_SCOPE_PROCESS ); iThCreateRes = pthread_create( &szThreadHandle, &t_attr, test2, (void *)777 ); if( iThCreateRes == 0 ) { } return ( bRet ); } void *test2( void *iParam ) { return (void*)0; } -------------------------------ここまで-------------------------------

  • 別ターミナルへのprintf出力

    LinuxでC言語プログラムから新しいターミナルを開き、そこにprintfで文字を出力したいのですがどうやったら良いのでしょうか?下記プログラムを作ってみましたが、新しいターミナルが開くだけで文字が出力されません #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <signal.h> void* thread(void* arg) {  int pid=0;  pid = fork();  if(pid==0)  {    execlp("gnome-terminal","gnome-terminal",NULL);     printf("Hello World!!\n");  } } int main() {   pthread_t th;  void* result;   pthread_create(&th, NULL,thread, NULL);  pthread_join( th,&result); }

  • pthread質問があります

    devc++を使ってpthreadの勉強をしてます pthread-win32 packageをinstall して実行をしたのですがerrorがでます 何の理由か分かりません 教えてください [Linker error] undefined reference to `_imp__pthread_attr_init' [Linker error] undefined reference to `_imp__pthread_attr_getscope' [Linker error] undefined reference to `_imp__pthread_attr_setscope' [Linker error] undefined reference to `_imp__pthread_create' [Linker error] undefined reference to `_imp__pthread_join' [Linker error] undefined reference to `_imp__pthread_exit' ld returned 1 exit status #include <pthread.h> #include <stdio.h> #define NUM_THREADS 5 void *runner(void *param); int main(int argc, char *argv[]) { int i, scope; pthread_t tid[NUM_THREADS]; pthread_attr_t attr; //get the default attributes pthread_attr_init(&attr); //first inquire on the current scope if(pthread_attr_getscope(&attr,&scope) != 0) fprintf(stderr, "Unable to get scheduling scope\n"); else { if(scope == PTHREAD_SCOPE_PROCESS) printf("PTHREAD_SCOPE_PROCESS"); else if(scope == PTHREAD_SCOPE_SYSTEM) printf("PTHREAD_SCOPE_SYSTEM"); else fprintf(stderr, "Illegal scope value.\n"); } //set the scheduling algorithm to PCS or SCS pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); //create the threads for(i=0;i<NUM_THREADS;i++) pthread_create(&tid[i],&attr,runner,NULL); //now join on each thread for(i=0;i<NUM_THREADS;i++) pthread_join(tid[i],NULL); getchar(); getchar(); return 0; } //each thread will begin control in this function void *runner(void *param) { //do some work pthread_exit(0); }

  • pthread_createでタスクの構造体にて

    pthread_createという関数でeventというスレッドタスクを作成したく、次のように宣言しました。 if(pthread_create(&thread03 , NULL , thread_func03 ,(void*)&pth) !=0) perror("pthread_create()"); ちなみに、pth_argは次のような構造です。 typedef struct{ char *c; int i; long l; }pth_arg; /* thread_func関数に値を渡すときの構造体 */ 実際のタスク void *event(void *param) { pth_arg *this_arg; this_arg = param; -----(中略)------------------------- } このような形ビルドも正常に完了し、this_argの構造をそのままこのタスク内で使用することも可能なのですが、その後に typedef struct{ char *c; int i; long l; }env_t; /* 次のような構造体もこのタスク内に追加したくなり、 実際のタスク env_t * pEnv; //グローバル宣言 void *event(void *param) { pth_arg *this_arg; this_arg = param; pEnv->i = 0x01; -----(中略)------------------------- } このように、env_t * pEnv;でグローバル宣言で宣言して 値を代入するようなコードを書くと、ビルドはOKなのですが、実行すると Segmentation fault (core dumped) このエラーが出てきて動作が停止してしまいます。 これを解決方法などありませんでしょうか? どうぞ、ご教示頂きますようお願い致します。

  • C言語

    ファイルデータ(11,22,33,0,44)を読み込んで表示することを5回繰り返すプログラムを作りたいのですが分かりません。 さらに出来ればファイルデータが0でなければ表示し、0を読み込んだら終了するwhile文でのプログラムも教えてください。 途中経過 #include <stdlib.h> #include <stdio.h> int main(void) { int x = 0,i; FILE *infile; infile = fopen ("test.txt", "r"); if(infile == NULL) { fprintf(stderr, "test.txtが開けません\n"); exit(1); } i = 0 while(1){ i++; fscanf(infile, "%d", &x); printf("%d\n", x); if(i = 5)break; } fclose(infile); return 0; } ここまでで実行すると11しか表示されません。 これまでの質問分かるかたどなたか教えてくださいお願いします。

  • なぜかわかりませんscanf()の戻り値で迷ってます。

    ある本にscanf()の書き方が書いてあってそれを入力してもエラーが表示されてわかりませ。 使用ソフトはMicrosoft Visual c++です。どこが間違っているのか教えてください。 #include <stdio.h> #include <stdlib.h> int main (void) { int score[10]; int status; int temp_score; int score_count; int i; /*配列に位に入力*/ score_count = 0; while(1){ status=scanf("d",&score_count); if (status == EOF ){ break; }else if (status != 1){ fprintf(stderr ,"入力エラー\n"); exit(1); } if (score_count >= 10 ){ fprintf( stderr,"データ件数が多すぎます\n"); exit(1); } score[score_count] =temp_score; score_count++; } } /*配置の内容を表示する*/ for(i=0 ;i < score_count;i++){ printf("score[%d]..%d\n",i,score[i]); } return (0); }

  • 別スレッドからメインスレッドのテキストボックスに文字を表示させたい

    Visual C++ 2005 Express Editionを使用している初心者です。 タイトルの方法がどうしてもわからないので教えてください。 うまく説明できないので聞きたいところのコードを載せます。 //SAMPLE.cpp #include "stdafx.h" #include "Form1.h" using namespace SAMPLE; int main(array<System::String ^> ^args) { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew Form1()); } //Form1.h #include <process.h> #include <vcclr.h> namespace SAMPLE { unsigned __stdcall counter(void *arg); int thread_id1; unsigned dummy; using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; public ref class Form1 : public System::Windows::Forms::Form { public:Form1(void) { InitializeComponent(); //別スレッド起動 thread_id1=_beginthreadex(NULL,0,counter,(void *)1,0,&dummy); } private: System::Windows::Forms::TextBox^ textBox1; private: System::ComponentModel::Container ^components; void InitializeComponent(void) { this->textBox1 = (gcnew System::Windows::Forms::TextBox()); //省略(コンポーネント初期化) } private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { } }; unsigned __stdcall counter(void *arg){ //別スレッド //ここで文字列を記述して上のtextBox1に表示したい return 0; } } 初歩的なことかもしれませんが、 よろしくお願いします。

専門家に質問してみよう