/*language C code*/
#include "windows.h"
typedef struct object_s
{
SRWLOCK lock;
int data;
} object_t, *object_p; /*own and pointer type*/
void thread(object_p x)
{
AcquireSRWLockExclusive(&x->lock);
//...do something that could probably change x->data value to 0
if(x->data==0)
free(x);
else
ReleaseSRWLockExclusive(&x->lock);
}
void main()
{
int i;
object_p object=(object_p)malloc(sizeof(object_t));
InitializeSRWLock(&object->lock);
for(i=0;i<3;i++)
CreateThread(0,0,thread,object,0);
}
Как вы можете понять из приведенных выше кодов, я должен дать одному потоку условно освободить объект, на котором могут блокироваться два других.Вышеприведенные коды явно ошибочны, потому что если объект освобождается вместе с блокировкой, все блокирующие потоки не дают нам ничего, кроме ошибки.
Решение ниже
/*language C code*/
#include "windows.h"
typedef struct object_s
{
/*change: move lock to stack in main()*/
int data;
} object_t, *object_p; /*own and pointer type*/
void thread(void * x)
{
struct {
PSRWLOCK l;
object_p o;
} * _x=x;
AcquireSRWLockExclusive(_x->l);
//...do something that could probably change x->data value to 0
if(_x->o->data==0)
free(_x->o);
ReleaseSRWLockExclusive(&x->lock);
}
void main()
{
int i;
SRWLOCK lock; /*lock over here*/
object_p object=(object_p)malloc(sizeof(object_t));
InitializeSRWLock(&lock);
/*pack for thread context*/
struct
{
PSRWLOCK l;
object_p o;
} context={&lock, object};
for(i=0;i<3;i++)
CreateThread(0,0,thread,&context,0);
}
работает в этом случае, но не применимооднако, в моем последнем проекте, потому что на самом деле есть динамический связанный список объектов.Применение этого решения означает, что должен быть соответствующий список блокировок, каждая блокировка для объекта и, более того, когда определенный объект освобождается, его блокировка должна быть одновременно снята.Нет ничего нового по сравнению с первым разделом кода.
Теперь мне интересно, есть ли альтернативное решение для этого.Большое спасибо!