2016-11-18 2 views
1

は、次のプログラムを考えてみましょう:C pthread:条件が満たされたときに1つのスレッドをアクティブにする方法は?

// Compilation: 
// gcc -Wall -Wextra -pedantic -Wno-unused-parameter -O3 test.c -o test -pthread 

// Include 
#include <time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <pthread.h> 
#include <semaphore.h> 

// Common variables 
sem_t sem;      // Semaphore 
static const int nthr = 4;  // Number of threads 
static int n = 0;    // Global counter 

// Wait for a given number of seconds 
void wait(unsigned int seconds) 
{ 
    unsigned int limit = time(NULL) + seconds; 
    while (time(NULL) < limit); 
} 

// Function f0 
void* f0(void* arg) 
{ 
    while (n < 2); // Here 
    // Doing stuff that does no require any access to shared variable 
    printf("...doing stuff in f0...\n"); 
    pthread_exit(NULL); 
} 

// Function fn 
void* fn(void* arg) 
{ 
    sem_wait(&sem); 
    wait(1); 
    printf("entering fn: n = %d\n", n); 
    n++; 
    printf("leaving fn: n = %d\n", n); 
    wait(1); 
    sem_post(&sem); 
    pthread_exit(NULL); 
} 

// Main 
int main(int argc, char* argv[]) 
{ 
    pthread_t thr[nthr]; 
    sem_init(&sem, 0, 1); 
    pthread_create(&thr[0], NULL, f0, NULL); 
    for (int i = 1; i < nthr; ++i) pthread_create(&(thr[i]), NULL, fn, NULL); 
    for (int i = 0; i < nthr; ++i) pthread_join(thr[i], NULL); 
    return 0; 
} 

プログラムは次の処理を行います。他のスレッドがfnを実行している間 thread0f0を実行します。私はf0が2つのスレッドが何かをする前にnがインクリメントされるまで待つことを望みます。

現在のところ、Hereのマークが付いていますが、動作しません。可能であれば、ミューテックスの代わりにセマフォーを使用して正しく行う方法は?

コメントで述べたようにあなたは、pthread_condを使用することができます
+1

pthread_cond_tを使用できます。 – sturcotte06

+1

はい、mutexを使って 'pthread_cond_wait'を使用してください。すべての条件が合図されたら、あなたは 'n'を読んで、続行するべきかどうかを調べるべきです。 –

+0

@JensMunkこのケースではどのように使用するのですか? – Vincent

答えて

0

https://linux.die.net/man/3/pthread_cond_init

IMO指揮もう少し複雑、あなたがマルチスレッドの世界で始めているので、もし、私が最初に使用することをお勧めしますですmutex_lock:この場合

http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_mutex_lock.html

、あなたは "N"(var_n_lock)variablでの書き込み/読み出しのために2つのロック、F0機能(f0_lock)ごとに1つのあなたが、その他を使用する必要がありますe。あなたのプログラムは:

  1. f0_lock lockedとvar_n_lock unlockedで始める必要があります。
  2. f0はf0_lockを待ちます。
  3. fnスレッドは必要な処理を行い、var_n_lockをロックし、nを1増やしてn == 2であるかどうかを確認します。そうであればf0_lockをロック解除し、最後にvar_n_lockをロック解除します。
  4. n == 2の場合、f0を実行しているスレッドはロックされずに実行され続けます。

fnスレッドがf0より前に終了するように見えます。その場合は、結合の順序を逆にする必要があります。その結果、最適化が小さくなります。また、あなたのプログラムがしばらく待つようにするには、sleepまたはusleepを使うと、CPUが大幅に節約されます。

これが役に立ちます。

関連する問題