pthread_mutex_lockの応答時間について

このQ&Aのポイント
  • 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_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割り当てに時間がかかった等も考えられるのかとは思いますが、スレッドライブラリとしての動きが知りたいです。

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

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1

>多少の時間がかかってしまうことはありうるのでしょうか ありうるでしょうね。スレッドがスリープ状態になり、起床のタイミングはOS任せになるでしょう。 それが問題になるケースの為に、スピンロック用のI/Fがあるようですから。 http://codezine.jp/article/detail/1893?p=2

nishimry
質問者

お礼

回答ありがとうございました。 spinlock用の関数もあったんですね。当方の現在のプログラムでspinして待つことは良くないと考えますが、リンクにあるspinとmutexの比較説明でpthreadライブラリについての理解が深まりました。 参考にさせていただきます。

関連するQ&A

  • pthread_mutex_unlock失敗?

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

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

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

    皆さんこんにちは。 当方、プログラミングを勉強中の学生です。 条件変数を用いた有限バッファ問題を考えております。 以下に示すソースにおいて、関数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; }

  • pthread_cond_waitとptherad_cond_signal

    pthread_cond_waitで寝ているthreadに対して、ptherad_cond_signalにて起こして、そのthreadが再度寝るまでの間にpthread_cond_signalが複数回(2回として)Callされた場合、どのような挙動になるのでしょうか? 最初のSignalをA、以下B,Cとすると A->cond_wait->B->cond_wait->C となるのでしょうか? 宜しくお願い致します。

  • 排他制御のためのロックについて

    &lock; #--->ロック処理 open(IN,"data.txt"); $data = <IN>; close(IN); &unlock; #--->アンロック処理(1) $data = $ENV{'REMOTE_ADDR'}.\n;#-->(2) &lock; #--->ロック処理(3) open (OUT,">>data.txt"); print OUT "$data"; close (OUT); &unlock; #--->アンロック処理 ということをした場合、一度目のアンロック処理((1))と、二度目のロック処理((3))の間は何もロックはしてないことになりますよね? もし、仮に(1)~(3)の処理をするのに3秒もかかるとします。 そのとき、 ・AとBの2人が別々のIPを持った状態で、上記が記述されたCGIに1秒差でアクセスして、「(2)」が2人によって1秒違いで実行される。 という場合では、二人の「$data」の値は同じIPアドレスになる(最初に実行した方が、後で実行された$dataの値によって上書きされる)のでしょうか? それとも、$dataの二人とも別々の本来のIPアドレスがdata.txtに書き込まれるのでしょうか? もし、同じIPアドレスになったとしたら、open~closeまでをロックするというのでは駄目なのでしょうか?

    • ベストアンサー
    • Perl
  • 並列プログラミングのエラー

    6400×6400の行列のベクトル積を並列計算によって求め、その時間を計るプログラムです。 #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <pthread.h> #define MATRIX 6400 #define THREAD 2 #define COUNT 30 #define SPLIT 100 int INDEX = 0; double a[MATRIX * MATRIX], b[MATRIX], x[MATRIX]; pthread_mutex_t m1; double gettimeofday_sec() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + (double)tv.tv_usec*1e-6; } void thread_func(void *arg) { int i, j, tmp; while(INDEX < MATRIX) { pthread_mutex_lock(&m1); tmp = INDEX; INDEX += SPLIT; pthread_mutex_unlock(&m1); for(i = tmp; i < tmp + SPLIT; i++) { for(j = 0; j < MATRIX; j++) { b[i] += a[i * MATRIX + j] * x[j]; } } } } int main() { int i, j; double timeA, timeB; pthread_t handle[THREAD]; pthread_mutex_init(&m1, NULL); for(i = 0; i < MATRIX * MATRIX; i++) a[i] = rand() % 10; for(i = 0; i < MATRIX; i++) x[i] = rand() % 10; timeA = gettimeofday_sec(); //計測開始 for(i = 0; i < COUNT; i++) { for(j = 0; j < THREAD; i++) pthread_create(&handle[i], NULL, (void *)thread_func, NULL); for(j = 0; j < THREAD; i++) pthread_join(handle[i], NULL); INDEX = 0; } timeB = gettimeofday_sec(); //計測終了 printf("計算時間:%d\n", timeB - timeA); return 0; } cygwinでコンパイル、実行すると Exception: STATUS_ACCESS_VIOLATION at eip=00401276 eax=000018D0 ebx=000018FF ecx=00000003 edx=0022CE64 esi=611021A0 edi=004015E8 ebp=0022CCE8 esp=0022CC90 program=C:\cygwin\home\管理者\a.exe, pid 2020, thread main cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023 Stack trace: Frame Function Args 0022CCE8 00401276 (00000001, 6116B690, 13F40090, 0022CC70) 0022CD98 610060D8 (00000000, 0022CDD0, 61005450, 0022CDD0) 61005450 61004416 (0000009C, A02404C7, E8611021, FFFFFF48) 7 [main] a 2020 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack) という内容のstackdumpファイルが生成されて実行できません。 どのように修正すればうまく実行できるでしょうか? 環境は OS:WindowsXP SP3 CPU:Intel(R) Core(TM)2 Duo E4500 @2.20GHz RAM:2048MB です。 よろしくお願いします。

  • lockについて

    $file = 'file.log'; ------------------------------------ sub a{ &lock;ロック 1: open(IN, $file); # ファイルを開く 2: $count = <IN>; # カウンターを読み出す 3: close(IN); # ファイルを閉じる 4: $count++; # カウンターをひとつ増やす 5: open(OUT, "> $file"); # ファイルを開く 6: print OUT "$count\n"; # ファイルにカウンタを書き込む 7: close(OUT); # ファイルを閉じる 8: print "$count\n"; &unlock;ロック解除 } ------------------------------------ sub b{ 1: open(IN, $file); # ファイルを開く 2: $count = <IN>; # カウンターを読み出す 3: close(IN); # ファイルを閉じる } ------------------------------------ サブルーチンaではロック処理を行っていますが、 サブルーチンbでは書き込む処理がないためロック処理を行っていません。 読み込むファイルは同じでなのですが、 サブルーチンbにもロック処理を入れた方がいいのでしょうか?

    • ベストアンサー
    • Perl
  • マルチスレッドのプログラミング

    以下に示された関数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 ↑ここらへんを参考にしているのですが、答えを導けません。 ご教示お願い致します。

専門家に質問してみよう