新的bie在这里。我一直在研究读者/作者的问题解决方案。它在一个阅读器和一个写入器的情况下工作得很好。但是当我将reader修改为2时,writer线程总是会饿死。帮帮我!
看起来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();
}发布于 2012-07-22 07:32:01
对于多个读取器线程,g_ReadCount很可能永远不会达到零,因此wrt互斥永远不会被释放(从而使编写器挨饿)。您可能需要某种类型的指示器来指示写线程正在等待。然后,读取器线程需要在某一时刻优先于写入器。
例如,在我写的一个实现中(不是说这是一种很好的方式,但它是有效的)我使用了一个标志,该标志是通过原子递增/递减操作设置/清除的,该标志指示写线程是否正在等待锁。如果是这样的话,读者会推迟阅读。当然,在这种情况下,您还需要小心相反的情况,即写入器线程(如果有多个)可能会使读取器饿死。读/写锁很棘手。
发布于 2012-07-23 03:49:03
在解决这个问题时,我发现了一个有趣的问题。
在研究过程中,我们告诉我们,最大计数=1的信号量等于互斥量。这并不完全正确。
1)互斥不能被其他线程释放。2)在这种情况下可以使用信号量。
https://stackoverflow.com/questions/11596599
复制相似问题