首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Readers Writers - Writer线程总是被多个reader线程卡住

Readers Writers - Writer线程总是被多个reader线程卡住
EN

Stack Overflow用户
提问于 2012-07-22 07:24:43
回答 2查看 899关注 0票数 1

新的bie在这里。我一直在研究读者/作者的问题解决方案。它在一个阅读器和一个写入器的情况下工作得很好。但是当我将reader修改为2时,writer线程总是会饿死。帮帮我!

看起来Writer线程在等待wrt互斥时被卡住了。

代码语言:javascript
复制
#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();


}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-22 07:32:01

对于多个读取器线程,g_ReadCount很可能永远不会达到零,因此wrt互斥永远不会被释放(从而使编写器挨饿)。您可能需要某种类型的指示器来指示写线程正在等待。然后,读取器线程需要在某一时刻优先于写入器。

例如,在我写的一个实现中(不是说这是一种很好的方式,但它是有效的)我使用了一个标志,该标志是通过原子递增/递减操作设置/清除的,该标志指示写线程是否正在等待锁。如果是这样的话,读者会推迟阅读。当然,在这种情况下,您还需要小心相反的情况,即写入器线程(如果有多个)可能会使读取器饿死。读/写锁很棘手。

票数 1
EN

Stack Overflow用户

发布于 2012-07-23 03:49:03

在解决这个问题时,我发现了一个有趣的问题。

在研究过程中,我们告诉我们,最大计数=1的信号量等于互斥量。这并不完全正确。

1)互斥不能被其他线程释放。2)在这种情况下可以使用信号量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11596599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档