pthread_createでタスクの構造体にて

このQ&Aのポイント
  • pthread_createという関数を使用して、スレッドタスクを作成しようとしています。
  • タスクの構造体に新しい構造体を追加し、その値を使用しようとしていますが、実行時にSegmentation fault (core dumped)エラーが発生しています。
  • この問題を解決するための方法を教えてください。
回答を見る
  • ベストアンサー

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) このエラーが出てきて動作が停止してしまいます。 これを解決方法などありませんでしょうか? どうぞ、ご教示頂きますようお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

>グローバル宣言ではダメなんでしょうか? 場所ではなく、前のソースで、 pEnv->i < ここまで一度も、この変数を使っていないのですよ。 なので、pEnvの値が不定 ポインタもどこも指していない状態(おそらく0だと思いますが) 今回、動いたのは、 env_t * pEnv; if(pthread_create(&thread03 , NULL , thread_func03 ,(void*)&pEnv) この2行のためですね。 ただし、間違っているかと。。 プロトタイプは、 int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg); の関数ですので、 (void*)&pEnv は、 void ** になっていませんか? (void*)pEnv < & は、いりません。 で、この関数を呼ぶ「前」に、 pEnvを初期化してください。 グローバルでもローカルでもOKです。 実体を持たないから、エラーが出ているだけなので、 実体を持たせれば、目的は達成されると思います。 env_t vEnv; < これなら実体 env_t *pEnv; < これなら参照体(要するにポインタ) ----------- env_t vEnv; これと if(pthread_create( ........................,(void*)&vEnv) これだけで、直ると思いますよ。 pEnvを使いたいのであれば、事前に初期化します。 env_t vEnv; < 実体 env_t *pEnv=&vEnv; < 実体を参照させた。 if(pthread_create( ........................,(void*)pEnv) &はなしで、そのまま、使う。 の2通りかな。 ほぼ、これで全部終りですね。

techhouse
質問者

お礼

回答頂きありがとうございます。お世話になっております。返事遅れてもうしわけありません。 解決できました。 この環境変数関連の構造体はちょっと別マイコンで使用していたプログラムを使っていたのですが、これをLinuxのgccプログラミングでも使えないかと思いやってみました。 実態がないというエラーだったのですね。 マイコンのプログラミングではこの実態に当たるところがSRAMのメモリのメモリ番地を指しているようでした。 env_t * pEnv; ----------------(中略)---------------- pEnv = (env_t *)(FLASH_ENV_ADDR + sizeof(env_hdr_t)); このような宣言をしていました。 FLASH_ENV_ADDRってのが0x600000番地とかなってました。 ポインターとか苦手だったのでとても助かりました。

その他の回答 (1)

回答No.1

実際のタスク env_t * pEnv; //グローバル宣言 void *event(void *param) { ~~~~ pEnv->i = 0x01;  <-ここ pEnvはどこで初期化しました? ポインタに実体がないので、セグメンテーションエラーがでただけではないかと 思いますが。 pEnv= なにか?の”実体”の代入がないと。 だと思いますが、 見当違いならすいません。

techhouse
質問者

お礼

回答頂きありがとうございます。 ”pEnvはどこで初期化しました?”ということに関して、勉強不足で初期化というのをどのようにやればよいかわからない状態です。 pthread_create(&thread03 , NULL , thread_func03 ,void*)&pth) このpthread_create関数の第4引数に設定した項目が初期化に当たりますでしょうか? main関数でenv_tをこのように宣言したら使えるようになりました。 int main(int argc, char *argv[]) { pth_arg pth; env_t * pEnv; --------(中略)---------------------------------- if(pthread_create(&thread03 , NULL , thread_func03 ,(void*)&pEnv) !=0) { perror("pthread_create()"); } --------(中略)---------------------------------- } このようにすることで void *event(void *param) { env_t * pEnv; pEnv = param; --------(中略)---------------------------------- pEnv->i = 0x01; --------(中略)---------------------------------- } このようにすることでpEnvが動作することができたのですが、 pthread_create関数の第4引数にデータをセットしなければ、スレッドでの構造体を使用することはできないのでしょうか? グローバル宣言ではダメなんでしょうか? どうぞ、ご教示頂きますよう、お願い致します。

関連するQ&A

  • 構造体の纏め方

    関数のポインタを使用して、 /* プロトタイプ宣言 */ void func1 ( void ); void func2 ( void ); void func3 ( void ); /*******************/ /* プロトタイプ纏める */ void ( *funcs[] ) ( void ) = { func1, func2, func3 }; /*********************/ と言うのが、構造体でも出来ないでしょうか?と言うのが質問です。 変数(添字)によって、見るべき構造体を自由に変更させたいと言うのが主な使用方法です。 typedef struct _tag { int arg1; int arg2; } tag; tag watch1 , watch2 , watch3; とある変数が1なら、watch1、とある変数が2なら、watch2、とある変数が3なら、watch3を見ると言うようなプログラムにしたくて、質問しました。 witch文を使うしかないのでしょうか? 良き回答、お待ちしています。

  • クラス内での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; } ################################################################ 宜しくお願い致します。 以上です。

  • 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; } ##############################################################

  • 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関数)

    以下のプログラムを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; } -------------------------------ここまで-------------------------------

  • スレッドのスケジューリングポリシーと優先順位の設定(pthread)

    こんにちは。今、マルチスレッドのプログラミングをする上で困っていることがあります。 pthread(スレッド)の優先順位をどのように変更するのかがわかりません。 また、メインの優先順位も変更したいのですがよくわかりません。 現在、↓のようにやっていますが、変更されていないような気がします。 間違っているようであればご指摘やアドバイスをいただけるとうれしいです。 宜しくお願いします。 ------------------------- int main(){ int policy; pthread_t th; pthread_attr_t th_att; struct sched_param scp; /* pthread の優先順位の変更 */ scp.sched_priority = 50; /* この値は適当です…*/ policy = SCHED_FIFO; pthread_attr_init(&th_att); pthread_attr_setschedpolicy(&th_att,policy,&scp) /* mainの優先順位の変更*/ scp.sched_priority = 30; /* この値は適当です…*/ pthread_setschedparam(pthread_self(),policy,&scp) pthread_create(&th,&th_att,(void*)func,NULL); . . .

  • pthread_cond_wait 取りこぼし?

    はじめまして。 pthreadのお勉強がてら、パイプライン処理を実装してみようととりあえず実証コードを書いてみましたが、うまく意図した動きをしてくれません。 やりたいことは、処理ステージが2つあって、メインからステージ1をキックし、ステージ1は自分の処理が終わったらステージ2をキックするといった動作です。(メイン、ステージ1、ステージ2を並列に動作させたい) 取りあえず連鎖的に動作するか試したいだけなので、ステージ間のデータの受け渡しとかは、後で考えるとします。 それで、以下のような単純なコードを書きました。 期待する結果は、最後に表示される数値が 10000, 10000, 10000 になることですが、実際は、10000, 4401, 4401 のようにステージ1,2が少なくなります。 一応、それなりに調べて条件変数のセオリーに従い書いたつもりなのですが、どうしてこうなるか、ご教授ください。 test.c (空白を全角にしてあります) ------ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> pthread_mutex_t   mutex1,           mutex2; pthread_cond_t   cond1,           cond2; int         ready1,           ready2; int         end1,           end2; int         count1,           count2; void * stage1( void *arg ) {   pthread_mutex_lock( &mutex1 );   while( 1 ) {     /* wait for my signal & job */     while ( ready1 == 0 ) {       pthread_cond_wait( &cond1, &mutex1 );     }     if ( end1 == 1 ){  /* is shutdown thread */       break;     }     /* my job. */     count1++;     /* job clear */     ready1 = 0;     /* forward next stage */     pthread_mutex_lock( &mutex2 );     ready2 = 1;     pthread_cond_signal( &cond2 );     pthread_mutex_unlock( &mutex2 );   }   pthread_mutex_unlock( &mutex1 );   return NULL; } void * stage2( void *arg ) {   pthread_mutex_lock( &mutex2 );   while( 1 ) {     while ( ready2 == 0 ) {       pthread_cond_wait( &cond2, &mutex2 );     }     if ( end2 == 1 ){       break;     }     count2++;     ready2 = 0;   }   pthread_mutex_unlock( &mutex2 );   return NULL; } int main( ) {   int     i;   pthread_t  t1,         t2;   pthread_mutex_init( &mutex1, 0 );   pthread_cond_init ( &cond1, 0 );   ready1 = 0;   end1  = 0;   count1 = 0;   pthread_create( &t1, 0, stage1, NULL );   pthread_mutex_init( &mutex2, 0 );   pthread_cond_init ( &cond2, 0 );   ready2 = 0;   end2  = 0;   count2 = 0;   pthread_create( &t2, 0, stage2, NULL );   for ( i=0; i<10000; i++ ){     pthread_mutex_lock( &mutex1 );     ready1 = 1;     pthread_cond_signal( &cond1 );     pthread_mutex_unlock( &mutex1 );   }   pthread_mutex_lock( &mutex1 );   ready1 = 1;   end1  = 1;   pthread_cond_signal( &cond1 );   pthread_mutex_unlock( &mutex1 );   pthread_join(t1, 0 );   pthread_cond_destroy( &cond1 );   pthread_mutex_destroy( &mutex1 );   pthread_mutex_lock( &mutex2 );   ready2 = 1;   end2  = 1;   pthread_cond_signal( &cond2 );   pthread_mutex_unlock( &mutex2 );   pthread_join(t2, 0 );   pthread_cond_destroy( &cond2 );   pthread_mutex_destroy( &mutex2 );   printf("%d, %d, %d\n", i, count1, count2);   return 0; } ------ gcc -o test -lpthread test.c 以上

  • 別ターミナルへの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); }

  • 構造体のメンバーの静的なサイズ取得

    構造体のメンバーをヘッダーファイル中で得たい場合、 以下のような方法以外になにか方法はないでしょうか? 単純に XXXX x;と宣言してそれを sizeof(x.chwk)と 使うというような方法以外で なにかあれば教えてください。 ---------------------------------------- typedef struct { char chwk[100]; } XXXX; typedef struct { char chwk[ sizeof(( (XXXX*)0)->chwk ) ]; } YYYY; main(int arc, char *arg[] ){ YYYY y; printf( " YYYY chwk size = %d\n", sizeof(y.chwk)); }

  • pThreadのメインでなぜsleep?

    Windowsとlinux環境で、pthreadをもちいて、動作確認などをしています。 こちらのサンプルを下に、じっけんしていたのですが。 http://www.ibm.com/developerworks/jp/linux/library/l-posix3/ ここのメインのコードに, sleep(2) という表記があります。 なぜここでsleepをしなければいけないんでしょうか? 実際に、削除してみると、スレッドの作業が途中で終了してしまいました。 このやり方だと、作業時間がわかっている場合は、いいのですが、 もしどれぐらい処理にかかるかわからない場合、困ると思います。 どのようにすれば、sleepを使わずに作業が終わるのをまつことができるでしょうか? int main(void) { int x; wnode *mywork; initialize_structs(); /* CREATION */ if (create_threads()) { printf("Error starting threads... cleaning up.\n"); join_threads(); dabort(); } pthread_mutex_lock(&wq.control.mutex); for (x=0; x<16000; x++) { mywork=malloc(sizeof(wnode)); if (!mywork) { printf("ouch! can't malloc!\n"); break; } mywork->jobnum=x; queue_put(&wq.work,(node *) mywork); } pthread_mutex_unlock(&wq.control.mutex); pthread_cond_broadcast(&wq.control.cond); printf("sleeping...\n"); sleep(2); printf("deactivating work queue...\n"); control_deactivate(&wq.control); /* CLEANUP */ join_threads(); cleanup_structs(); }