此处为新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) 在这种情况下可以使用信号量。