1

ここで新しいビー。私はリーダー/ライターの問題解決に取り組んできました。1 つのリーダーと 1 つのライターで完全に正常に動作します。しかし、リーダーを2に変更すると; 書き込みスレッドは常に飢えています。助けて!

Writer スレッドがどこかで wrt ミューテックスを待っているようです。

#include <stdio.h>
#include <conio.h>
#include <windows.h>

HANDLE mutex, wrt;
int g_ReadCount = 0;
int g_GlobalData=0;

const int max = 2;
HANDLE reader[max], writer[max];
CRITICAL_SECTION rSect, wSect;
bool bTerminate = true;

DWORD Readers(LPVOID lpdwThreadParam ) 
{
  while(bTerminate)
  {
    WaitForSingleObject(mutex, INFINITE);
    g_ReadCount++;
    if(g_ReadCount == 1)
    {      
      WaitForSingleObject(wrt, INFINITE);
    }
    ReleaseMutex(mutex);

    EnterCriticalSection(&wSect);
    printf("ThreadId : %d --> Read data : %d  ReaderCount %d\n", GetCurrentThreadId(), g_GlobalData, g_ReadCount);
    LeaveCriticalSection(&wSect);

    WaitForSingleObject(mutex, INFINITE);
    g_ReadCount--;
    if(g_ReadCount == 0)
    {
        ReleaseMutex(wrt);
        printf("ThreadId : %d Realesed Mutex wrt\n", GetCurrentThreadId());
    }
    printf("ThreadId : %d ReaderCount %d\n", GetCurrentThreadId(), g_ReadCount);
    ReleaseMutex(mutex);
    printf("Reader ThreadId : %d Realesed Mutex mutex\n", g_ReadCount);
    Sleep(0);
   }
  return 0;
}


DWORD Writers(LPVOID lpdwThreadParam ) 
{
  int n = GetCurrentThreadId();
  int temp = 1;
  while(bTerminate)
  {  
    printf("ThreadId : %d Waiting for WRT\n", GetCurrentThreadId());
    WaitForSingleObject(wrt, INFINITE);
    printf("WRITER ThreadId : %d ***Got  WRT\n", GetCurrentThreadId());
    ++n;
    temp++;

    if(temp == 100)
    {
      //bTerminate = false;
    }

    EnterCriticalSection(&wSect);
    printf("Write by ThreadId : %d Data : %d   Temp %d\n", GetCurrentThreadId(), n, temp);
    g_GlobalData = n;
    LeaveCriticalSection(&wSect);
    ReleaseMutex(wrt);
  }

  printf("***VVV***Exiting Writer Thread\n");
  return 0;
}

void main()
{
  mutex = CreateMutex(NULL, false, "Writer");
  wrt = CreateMutex(NULL, false, "wrt");

  InitializeCriticalSection(&rSect);
  InitializeCriticalSection(&wSect);
  DWORD dwThreadId = 0;



  for(int i=0; i < max; i++)
  {
    reader[i] = CreateThread(NULL, //Choose default security
      0, //Default stack size
      (LPTHREAD_START_ROUTINE)&Readers,
      //Routine to execute
      (LPVOID) 0, //Thread parameter
      0, //Immediately run the thread
      &dwThreadId //Thread Id
      );
  }

  for(int i=0; i < 1; i++)
  {
    writer[i] = CreateThread(NULL, //Choose default security
      0, //Default stack size
      (LPTHREAD_START_ROUTINE)&Writers,
      //Routine to execute
      (LPVOID) 0, //Thread parameter
      0, //Immediately run the thread
      &dwThreadId //Thread Id
      );
  }


  getchar();


}
4

2 に答える 2

1

複数のリーダー スレッドがあるg_ReadCount場合、ゼロにならない可能性が非常に高いため、wrtミューテックスが解放されることはありません (したがって、ライターが枯渇します)。おそらく、ライター スレッドが待機していることを示す何らかのインジケータが必要です。次に、ある時点で、リーダー スレッドがライターを優先する必要があります。

たとえば、私が書いた実装の 1 つ (それが素晴らしい方法だとは言いませんが、うまくいきました) では、ライター スレッドがロックを待っているかどうかを示すアトミック インクリメント/デクリメント操作によって設定/クリアされるフラグを使用しました。もしそうなら、読者は手を差し伸べるだろう。もちろん、その場合、書き込みスレッド (複数の場合) が読み取りスレッドを枯渇させる可能性がある反対の状況にも注意する必要があります。読み取り/書き込みロックは注意が必要です。

于 2012-07-21T23:32:00.580 に答える
0

この問題に取り組んでいる間; 興味深い問題を見つけました。

勉強中。最大カウント = 1 のセマフォは Mutex と等しいと言いました。それは完全に真実ではありません。

1) ミューテックスは他のスレッドから解放できません。2) このような場合にセマフォを使用できます。

于 2012-07-22T19:49:03.200 に答える