读者作家 - 作家线程始终坚持多个读者线程

时间:2012-07-21 23:24:43

标签: c++ windows multithreading writers

新bie在这里。 我一直致力于读者/作家的问题解决方案。 它与1位读者和1位作家完美搭配。 但是当我修改读者到2;作家线程总是挨饿。救救我!

似乎Writer线程卡在某处等待wrt mutex。

#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();


}

2 个答案:

答案 0 :(得分:1)

如果有超过1个读者线程,g_ReadCount很可能永远不会为零,因此永远不会释放wrt互斥锁(从而使编写者挨饿)。你可能需要写作者线程正在等待的某种指示器。然后读者线程需要在某些时候优先考虑作者。

例如,在我写的一个实现中(不是说这是一个好方法,但它有效)我使用了一个标志,通过原子递增/递减操作设置/清除,表明编写器线程是否在等待锁定。如果是这样,读者会推迟。当然,在这种情况下,您还需要注意相反的情况,即编写者线程(如果不止一个)可能会使读者挨饿。读/写锁很棘手。

答案 1 :(得分:0)

在解决这个问题时;我找到了有趣的问题。

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

1)任何其他线程都无法释放互斥锁。 2)在这种情况下可以使用信号量。