Пройдя через этот вопрос с тем же заголовком и его ответы , я подумал попробовать что-то, что действительно должно работать только с использованием критической секции и, следовательно, должно быть намного быстрее, чем существующие решения (которые также используют другие объекты ядра, такие как мьютекс или семафор)
Вот мои функции блокировки/разблокировки чтения/записи:
#include <windows.h>
typedef struct _RW_LOCK
{
CRITICAL_SECTION readerCountLock;
CRITICAL_SECTION writerLock;
int readerCount;
} RW_LOCK, *PRW_LOCK;
void InitLock(PRW_LOCK rwlock)
{
InitializeCriticalSection(&rwlock->readerCountLock);
InitializeCriticalSection(&rwlock->writerLock);
}
void ReadLock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->readerCountLock); // In deadlock 1 thread waits here (see description below)
if (++rwlock->readerCount == 1)
{
EnterCriticalSection(&rwlock->writerLock); // In deadlock 1 thread waits here
}
LeaveCriticalSection(&rwlock->readerCountLock);
}
void ReadUnlock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->readerCountLock);
if (--rwlock->readerCount == 0)
{
LeaveCriticalSection(&rwlock->writerLock);
}
LeaveCriticalSection(&rwlock->readerCountLock);
}
int WriteLock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->writerLock); // In deadlock 3 threads wait here
}
void WriteUnlock(PRW_LOCK rwlock)
{
LeaveCriticalSection(&rwlock->writerLock);
}
А вот функция потока. После вызова InitLock (&g_rwLock);
из main
я создал ПЯТЬ потоков, чтобы попробовать эти блокировки.
void thread_function()
{
static int value = 0;
RW_LOCK g_rwLock;
while(1)
{
ReadLock(&g_rwlLock);
BOOL bIsValueOdd = value % 2;
ReadUnlock(&g_rwlLock);
WriteLock(&g_rwlLock);
value ++;
WriteUnlock(&g_rwlLock);
}
}
В идеале этот код должен работать вечно без каких-либо проблем. Но, к моему разочарованию, он не работает всегда. Иногда это заходит в тупик. Я скомпилировал это и запустил на Windows XP. Для создания потоков с использованием пула потоков я использую стороннюю библиотеку. Следовательно, здесь нельзя привести весь этот код, который включает в себя множество процедур инициализации и прочего.
Но, чтобы сократить историю, я хотел бы знать, может ли кто-нибудь, глядя на приведенный выше код, указать, что не так с этим подходом?
В приведенном выше коде я прокомментировал, что каждый поток (из ПЯТИ потоков) ожидает возникновения взаимоблокировки. (Я обнаружил это, подключив отладчик к заблокированному процессу)
Любые входные данные/предложения были бы действительно замечательными, поскольку я застрял на этом уже довольно давно (в жадности заставить мой код работать быстрее, чем когда-либо).
InitLock
звонили изmain
. Я понял, что при публикации произошли ошибки. Я действительно в стрессе :( Позвольте мне попытаться подготовить код, который не будет использовать какую-либо стороннюю библиотеку, и опубликовать его здесь. - person Atul   schedule 02.12.2014readerCount
будет значительно быстрее, чем критический раздел. - person Harry Johnston   schedule 02.12.2014