2016-10-21 7 views
0

スレッド間の同期を介してコンテキスト切り替えをシミュレートしようとしています(現在は2から始まります)。各スレッドがプロセスとして動作し、 TIMESLICEインターバル(現在は3ミリ秒)。一度に1つのスレッドのみを実行してスレッドを切り替えることは完全に実行されていますが、最初のスレッドが終了しても呼び出しスレッドのプリエグ出口で実行されたpthread_cond_signalは他のスレッドのpthread_cond_waitを起動しません。私の頭の上オフ呼び出しスレッドが終了する前にpthread_cond_signalが他のスレッドに到達しない

#include<stdio.h> //for printf 
#include<pthread.h> //for threads, mutual exclusion, conditional wait and signalling 
#include<time.h> //for accurate clock time 
#include<limits.h> //for min-max limits of several data types 
#include<inttypes.h> //for using uint64_t data type 

#define bool int 
#define true 1 
#define false 0 

#define TIMESLICE 3000000 //nanoseconds to define milliseconds 
#define BILLION 1000000000L 

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t lock_t = PTHREAD_MUTEX_INITIALIZER; 
int numProcWait = 2; 

void *threadFunction(void *arg) { 
    int i; 
    uint64_t diff=0; 
    bool locked,unlockCheck=true; // locked for synchronizing the thread withing itself 
    // unlock check for if the for loop exits without unlocking the mutex and without signalling the other thread 

    struct timespec start, end; 
    pthread_cond_wait(&cond,&lock_t); 
    pthread_mutex_lock(&lock); 

    clock_gettime(CLOCK_MONOTONIC, &start); 

    locked = true; 
    for (i = 0; i < INT_MAX/2048; i++) { 

     if(locked==false) { 
      pthread_mutex_lock(&lock); 
      printf("Lock acquired by Thread id: %lu\n",pthread_self()); 
      locked = true; 
      diff = 0; 
      clock_gettime(CLOCK_MONOTONIC, &start); 
     } 
     clock_gettime(CLOCK_MONOTONIC, &end); 
     diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec; 
     unlockCheck = true; 

     if(diff > TIMESLICE) { 

      if(i==INT_MAX-1) 
       unlockCheck = false; 

      if(numProcWait>1) { 
       locked = false;  
       printf("Lock released by Thread id: %lu\n",pthread_self()); 
       printf("Diff Time: %" PRIu64 " ms\n\n",diff/1000000); 

       pthread_mutex_unlock(&lock); 
       printf("Unlocking from thread Successful! Thread ID: %lu\n\n",pthread_self()); 
       pthread_cond_signal(&cond); 
       printf("Waiting Thread id: %lu\n\n",pthread_self()); 
       pthread_cond_wait(&cond,&lock_t); 
       printf("Received Signal Successful! Thread ID: %lu\n\n",pthread_self()); 
      } 
     } 
    } 
    //this condition would occur false on a very rare case 
    if(unlockCheck) { 
     printf("Lock released from out of the loop by Thread id: %lu\n\n",pthread_self()); 
     //this condition is executed but it doesn't wakes up the pthread_cond_wait function of the other thread. 
     pthread_mutex_unlock(&lock); 
     pthread_cond_signal(&cond);  
    } 

    printf("EXITING THREAD: %lu\n\n",pthread_self()); 
    numProcWait--; 
    printf("Number of processes waiting: %d\n\n",numProcWait); 
    return NULL; 
} 

int main() { 

    pthread_t tid[2]; 
    uint64_t diff; 
    struct timespec start, end; 

    clock_gettime(CLOCK_MONOTONIC, &start); 

    pthread_create(&tid[0], NULL, threadFunction, NULL); 
    pthread_create(&tid[1], NULL, threadFunction, NULL); 

    sleep(1); 
    pthread_cond_broadcast(&cond); 

    pthread_join(tid[0], NULL); 
    printf("Thread 1 EXITED. No. of Waiting Processes: %d\n",numProcWait); 
    //pthread_cond_signal(&cond); 
    pthread_join(tid[1], NULL); 
    printf("Thread 2 EXITED. No. of Waiting Processes: %d\n",numProcWait); 
    clock_gettime(CLOCK_MONOTONIC, &end); 
    diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec; 

    printf("Total Run Time: %" PRIu64 " ms\n",diff/1000000); 
    pthread_mutex_destroy(&lock); 
    pthread_cond_destroy(&cond); 
} 
+1

の可能性のある重複した[pthreadの\ _cond \ _WAIT(の理解)とのpthread \ _cond \ _signal()](http://stackoverflow.com/questions/16522858/understanding-of-pthread-cond-wait -nd-pthread-cond-signal) –

+1

あなたのコードは、関連する 'pthread_mutex_t'を保持せずに' pthread_cond_wait() 'を呼び出すための未定義の動作を引き起こします。 – EOF

答えて

0

:ここ

は、Cプログラムでコードの問題は、それが2つのミューテックス、ロックやlock_tを使用していることのようです。コードはロックをロックし、lock_tをargとしてpthread_cond_waitを呼び出します。

lock_t mutexを削除して1つのmutexだけを使用することをお勧めします。

+0

私はあなたのソリューションを試して、1つのミューテックスしか使用しませんでした。それは実行されず、デッドロックになります。 –

0

以下のようにcondition waitとsignalを呼び出す前に、mutexをロックする必要があります。

待ち:

pthread_mutex_lock(&lock_t); 
pthread_cond_wait(&cond,&lock_t); 
pthread_mutex_unlock(&lock_t); 

信号:

pthread_mutex_lock(&lock_t); 
pthread_cond_signal(&cond); 
pthread_mutex_unlock(&lock_t); 
0

あなたはすべての最初の

間違った条件付きの変数を使用している、あなたは pthread_cond_wait()

を呼び出す前にロックを取得する必要がありますしかしあなたのロジックは間違っている、

  pthread_mutex_unlock(&lock); 
      printf("Unlocking from thread Successful! Thread ID: %lu\n\n",pthread_self()); 
      pthread_cond_signal(&cond); 

      // you need to lock here, but its undefined which thread will 
      // acquire the lock first, so its possible, that the same thread 
      // will acquire the lock instantly again 
      // -> mutex are not fair! 
      pthread_mutex_lock(&lock_t);     

      printf("Waiting Thread id: %lu\n\n",pthread_self()); 
      pthread_cond_wait(&cond,&lock_t); 
      printf("Received Signal Successful! Thread ID: %lu\n\n",pthread_self()); 

は、スリープ状態(悪い考え)を追加するか、グローバル変数を設定して、現在実行中のスレッドを示すことができます。

int current_thread=0; 

、その後、あなたは current_thread = NEXT_THREADにすべてのcond_waitを調整する必要があります。 pthread_mutex_unlock(&ロック); printf( "スレッドからのロック解除が成功しました!スレッドID:%lu \ n \ n"、pthread_self()); pthread_cond_signal(& cond);

  pthread_mutex_lock(&lock_t);     
      while (current_thread != YOUR_LOCAL_THREAD_ID) { 
       pthread_cond_wait(&cond,&lock_t); 
      } 

      printf("Received Signal Successful! Thread ID: %lu\n\n",pthread_self()); 
関連する問題