读者-作家-作家线程总是与多个读者线程纠缠在一起



此处为新bie。我一直致力于读者/作家问题的解决方案。它与一个读者和一个作者完美结合。但当我将reader修改为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 %dn", GetCurrentThreadId(), g_GlobalData, g_ReadCount);
    LeaveCriticalSection(&wSect);
    WaitForSingleObject(mutex, INFINITE);
    g_ReadCount--;
    if(g_ReadCount == 0)
    {
        ReleaseMutex(wrt);
        printf("ThreadId : %d Realesed Mutex wrtn", GetCurrentThreadId());
    }
    printf("ThreadId : %d ReaderCount %dn", GetCurrentThreadId(), g_ReadCount);
    ReleaseMutex(mutex);
    printf("Reader ThreadId : %d Realesed Mutex mutexn", g_ReadCount);
    Sleep(0);
   }
  return 0;
}

DWORD Writers(LPVOID lpdwThreadParam ) 
{
  int n = GetCurrentThreadId();
  int temp = 1;
  while(bTerminate)
  {  
    printf("ThreadId : %d Waiting for WRTn", GetCurrentThreadId());
    WaitForSingleObject(wrt, INFINITE);
    printf("WRITER ThreadId : %d ***Got  WRTn", GetCurrentThreadId());
    ++n;
    temp++;
    if(temp == 100)
    {
      //bTerminate = false;
    }
    EnterCriticalSection(&wSect);
    printf("Write by ThreadId : %d Data : %d   Temp %dn", GetCurrentThreadId(), n, temp);
    g_GlobalData = n;
    LeaveCriticalSection(&wSect);
    ReleaseMutex(wrt);
  }
  printf("***VVV***Exiting Writer Threadn");
  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();

}

如果有一个以上的读取器线程,g_ReadCount很可能永远不会为零,因此wrt互斥锁永远不会被释放(从而使编写器挨饿)。您可能需要某种指示器来指示编写器线程正在等待。然后,在某个时刻,读取器线程将需要优先于编写器。

例如,在我编写的一个实现中(并不是说这是一个很好的方法,但它确实有效),我使用了一个通过原子递增/递减操作设置/清除的标志,该标志指示编写器线程是否在等待锁定。如果是这样的话,读者会拖延。当然,在这种情况下,你也需要小心相反的情况,即作者线程(如果不止一个)可能会让读者挨饿。读/写锁很棘手。

处理此问题时;我发现了一个有趣的问题。

研究期间;我们告诉最大计数为1的信号量等于Mutex。这并不完全正确。

1) Mutex不能由任何其他线程释放。2) 在这种情况下可以使用信号量。

相关内容

  • 没有找到相关文章

最新更新