• 締切済み

pthread_mutex_unlock失敗?

pthreadプログラムで、mutex_lockするスレッドとmutex_unlockするスレッドが別スレッドとなっている場合、mutex_unlockが失敗することはあるでしょうか。mutexの初期設定(mutex_init)時、スレッドの属性は特に指定していません。 OSはHP-UXでCでコードを記述しています。 単発のプログラムで動作確認をした限りでは無事にunlockされているようでした。 (lockスレッドとunlockスレッドが別ということ自体が少し危険なことだとは思うのですが・・・)

みんなの回答

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

Linuxのpthread実装の場合ですが http://www.linux.or.jp/JM/html/glibc-linuxthreads/man3/pthread_mutex_unlock.3.html を見ると、エラー検査を行うmutexの場合にはpthread_mutex_unlockがEPERMを返すようです。 > lockスレッドとunlockスレッドが別ということ自体が少し危険なことだとは思うのですが・・・ 「少し危険」どころか、プログラムの設計をやり直したほうが良いように思われます。

nishimry
質問者

お礼

ご回答ありがとうございました。 リンクを確認しました。 プログラムではmutexの設定をデフォルトで行っていますので、unlockでは常にアンロック状態に戻すとなっていましたが、実は戻すことができない状況もありえるのではないかと考えています。(OSの違い(LINUXとHP-UX)ということもありますが。) 過去に作成されたスレッドプログラムで発生した障害調査として確認していますので、設計の見直しにこぎつけるにはまず障害の原因を究明しなければならないのですが、やはり「設計に難有り」ですよね。

関連するQ&A

  • pthread_mutex_lock の応答時間

    HP-UX上でCを使ってpthreadプログラムを記述しています。 mutexを競合するスレッドが2つあり、  A) pthread_mutex_lock(&mutex)  B) pthread_mutex_lock(&mutex)  A) pthread_mutex_unlock(&mutex) の流れで処理が流れています。 この時、A)がlockを解放してからB)がlockを獲得できるまで(=pthread_mutex_lockの応答が返ってくるまで)に多少の時間がかかってしまうことはありうるのでしょうか。(現在発生している事象では、0.002秒程度) マシン性能にも拠ると思いますし、B)スレッドが再開するときのCPU割り当てに時間がかかった等も考えられるのかとは思いますが、スレッドライブラリとしての動きが知りたいです。

  • pthread_cond_wait での mutex

    以下の様なサンプルプログラム(一部省略)があります。 bossスレッドが1秒ごとにworkerスレッドを起こして、workerスレッドは処理後、再び眠ります。 worker () { while (...) { * pthread_mutex_lock(&g_lock); pthread_cond_wait(&g_signal, &g_lock); * pthread_mutex_unlock(&g_lock); : } } boss() { while (...) { wait( 1 ); * pthread_mutex_lock(&g_lock); pthread_cond_signal(&g_signal) * pthread_mutex_unlock(&g_lock); } } waitで待機し、signalで起こされるのはわかるのですが、 mutexでロックしている意味がわかりません。 mutexが不必要な処理の場合、*部分はいらないのでしょうか?

  • 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 以上

  • 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(); }

  • pthread_attr_tへの値の代入について

    スレッドを作成する際に、 属性としてPTHREAD_CREATE_DETACHEDを指定したいのですが、 その際pthread_attr_tをどのように設定したらよいかわかりません。 現在書いているコードは pthread pt; pthread_attr_t* attr; pthread_attr_init(attr); pthread_attr_setdetachstate(attr,PTHREAD_CREATE_DETACHED); if (pthread_create(&pt,attr,NULL,NULL) != 0){ perror("thread_create()"); exit(1); } 上記のようなものです。(スレッド作成部分のattr以外の 引数は適当です) これでコンパイルすると 警告: 変数 attr には値が代入されていません. と、警告が出てしまいます。 これを解消するにはどう修正したらよいのでしょうか?

  • pthread_self APIの高速化

    HP-UX上でCを使ってスレッドプログラムを書いています。 プログラム内部でスレッドIDを変数に保持して、その変数を元に、pthread_detachなどのAPIをコールするような作りになっているのですが、pthread_self APIで毎回、自スレッドIDを取得するようにすると、処理スピードは遅くなるのでしょうか。(どれくらい?気にするほど?) 感覚的には遅くなりそうな気がしてはいますが、プログラム変数の場合だと、予期しない変数の書き換えが発生した場合(これはこれでバグですので対応が必要になりますが・・・)などに余計な影響を受けることになり、どっちが得策なのか考えあぐんでいます。

  • 条件変数を用いた有限バッファ問題を考えています。

    皆さんこんにちは。 当方、プログラミングを勉強中の学生です。 条件変数を用いた有限バッファ問題を考えております。 以下に示すソースにおいて、関数produce()は1から1000までの整数を順に生成し、関数consume()はバッファから取り出した値の合計(1から1000までの和、500500となる)を求めるようプログラミングしているつもりなのですが、コンパイルして実行すると思ったような結果となりません。 どこが間違っているかご教授いただければ幸いです。 よろしくお願い致します。 以下、ソースとなります。 #include <stdio.h> #include <pthread.h> #define N 5 int buffer[N]; int inptr = 0, outptr = 0; int count = 0; int i = 0; int j = 0; int sum = 0; pthread_cond_t full = PTHREAD_COND_INITIALIZER; pthread_cond_t empty = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; int produce (void) { i += 1; return i; } void consume (int x) { j += 1; sum += x; } void *producer(void *arg) { int data; for (;;) { if (i >= 1000) break; data = produce(); pthread_mutex_lock(&lock); while (count > N) pthread_cond_wait(&full, &lock); count = count + 1; buffer[inptr] = data; inptr = (inptr + 1) % N; pthread_mutex_unlock(&lock); pthread_cond_signal(&empty); } } void *consumer(void *arg) { int data; for (;;) { if (j >= 1000) break; pthread_mutex_lock(&lock); while (count == 0) pthread_cond_wait(&empty, &lock); count = count - 1; data = buffer[outptr]; outptr = (outptr + 1) % N; pthread_mutex_unlock(&lock); pthread_cond_signal(&full); consume(data); } } int main() { pthread_t a, b; pthread_create(&a, NULL, producer, NULL); pthread_create(&b, NULL, consumer, NULL); pthread_join(a, NULL); pthread_join(b, NULL); printf("sum = %d\n", sum); return 0; }

  • libxml2 make 失敗

    CentOS-6.2で開発用のAPサーバを構築中です。 「libxml2」をmake install したいのですが、makeが上手くいっていないように思います。 「libxml2-2.6.26」が現在インストールされているのですが、「libxml2-2.6.30」を導入しようとしています。色々調べて実施しているのですが、ログを読み取れていないので苦戦しています。。 何が原因なのでしょうか。 以下に気になる箇所のログを記載しました。 よろしくお願いいたします。 ※補足 rpmでインストールも試したのですが、それも「依存性の欠如」エラーで上手くいかない状況です。 インストールされているのに「ない」とエラーが出たりです・・・ threads.c:57: warning: redundant redeclaration of 'pthread_once' /usr/include/pthread.h:466: warning: previous declaration of 'pthread_once' was here threads.c:59: warning: redundant redeclaration of 'pthread_getspecific' /usr/include/pthread.h:1076: warning: previous declaration of 'pthread_getspecific' was here threads.c:62: warning: redundant redeclaration of 'pthread_setspecific' /usr/include/pthread.h:1080: warning: previous declaration of 'pthread_setspecific' was here threads.c:65: warning: redundant redeclaration of 'pthread_key_create' /usr/include/pthread.h:1070: warning: previous declaration of 'pthread_key_create' was here threads.c:67: warning: function declaration isn't a prototype threads.c:67: warning: redundant redeclaration of 'pthread_mutex_init' /usr/include/pthread.h:720: warning: previous declaration of 'pthread_mutex_init' was here threads.c:69: warning: function declaration isn't a prototype threads.c:69: warning: redundant redeclaration of 'pthread_mutex_destroy' /usr/include/pthread.h:724: warning: previous declaration of 'pthread_mutex_destroy' was here threads.c:71: warning: function declaration isn't a prototype threads.c:71: warning: redundant redeclaration of 'pthread_mutex_lock' /usr/include/pthread.h:732: warning: previous declaration of 'pthread_mutex_lock' was here threads.c:73: warning: function declaration isn't a prototype threads.c:73: warning: redundant redeclaration of 'pthread_mutex_unlock' /usr/include/pthread.h:743: warning: previous declaration of 'pthread_mutex_unlock' was here threads.c:75: warning: function declaration isn't a prototype threads.c:75: warning: redundant redeclaration of 'pthread_cond_init' /usr/include/pthread.h:927: warning: previous declaration of 'pthread_cond_init' was here threads.c:77: warning: function declaration isn't a prototype threads.c:431: warning: unused variable 'err' testapi.c:17978: 警告: ‘gen_xmlSchematronPtr’ defined but not used testapi.c:17981: 警告: ‘des_xmlSchematronPtr’ defined but not used testapi.c:17998: 警告: ‘gen_xmlSchematronParserCtxtPtr’ defined but not used testapi.c:33930: 警告: ‘gen_xmlSAXHandlerPtr_ptr’ defined but not used testapi.c:33933: 警告: ‘des_xmlSAXHandlerPtr_ptr’ defined but not used make[3]: ディレクトリ `/home/myapp/libxml2-2.6.30/doc/examples' から出ます make[3]: ディレクトリ `/home/myapp/libxml2-2.6.30/doc' に入ります make[3]: `all-am' に対して行うべき事はありません. make[3]: ディレクトリ `/home/myapp/libxml2-2.6.30/doc' から出ます I/O error : Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ../doc/news.html:2: warning: failed to load external entity "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" reating gjobread make[2]: ディレクトリ `/home/myapp/libxml2-2.6.30/example' から出ます Making all in xstc make[2]: ディレクトリ `/home/myapp/libxml2-2.6.30/xstc' に入ります make[2]: `all' に対して行うべき事はありません. make[2]: ディレクトリ `/home/myapp/libxml2-2.6.30/xstc' から出ます make[1]: ディレクトリ `/home/myapp/libxml2-2.6.30' から出ます

  • スレッドの作成について(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; } -------------------------------ここまで-------------------------------

  • マルチスレッドのプログラミング

    以下に示された関数transferは、与えられた2つのスタックstack1とstack2に対し、stack1から要素と取り出してstack2に入れる操作を目的として実装したものである。複数のスレッドがこの関数を呼ぶ可能性がある場合にはこの関数が目的通りに機能しない場合がある。 (1)機能しない場合の例を挙げよ。 (2)この関数を目的通りに機能させるための修正案を2つ示せ。 (3)前問で挙げた修正案のうち、どちらが並列性を高める上では優位であるかを論ぜよ。 void transfer(Stack stack1, Stack stak2) { if(stack1 == stack2) return; stack1.mutex_lock(); Item item =stack1.pop(); if(item !=null) { stack2.mutex_lock(); stack2.push(item;) stack2.mutex_unlock() } stack1.mutex_unlock() } http://docs.oracle.com/cd/E19683-01/816-3976/sync-45513/index.html ↑ここらへんを参考にしているのですが、答えを導けません。 ご教示お願い致します。