使用Windows slim读/写锁 /*语言C代码*/ #包括“windows.h” 类型定义结构对象 { 锁; int数据; }对象t,*对象p/*自身和指针类型*/ 无效线程(对象_p x) { AcquireSRWLockExclusive(&x->lock); //…执行一些可能会将x->data值更改为0的操作 如果(x->data==0) 免费(x); 其他的 ReleaseSRWLockExclusive(&x->lock); } void main() { int i; object_p object=(object_p)malloc(sizeof(object_t)); 初始化swlock(&object->lock); 对于(i=0;il); //…执行一些可能会将x->data值更改为0的操作 如果(x->o->data==0) 自由(x->o); ReleaseSRWLockExclusive(&x->lock); } void main() { int i; SRWLOCK lock;/*锁在这里*/ object_p object=(object_p)malloc(sizeof(object_t)); 初始化swlock(&lock); /*线程上下文的包*/ 结构 { PSRWLOCK l; 对象(p o),; }上下文={lock,object}; 对于(i=0;i
而言,解决方案是不将锁与数据一起分配。我建议您将数据移出该结构,并将其替换为指向该数据的指针。然后,您的链接列表可以先释放数据,然后释放节点,而不会出现任何问题。以下是一些伪代码:使用Windows slim读/写锁 /*语言C代码*/ #包括“windows.h” 类型定义结构对象 { 锁; int数据; }对象t,*对象p/*自身和指针类型*/ 无效线程(对象_p x) { AcquireSRWLockExclusive(&x->lock); //…执行一些可能会将x->data值更改为0的操作 如果(x->data==0) 免费(x); 其他的 ReleaseSRWLockExclusive(&x->lock); } void main() { int i; object_p object=(object_p)malloc(sizeof(object_t)); 初始化swlock(&object->lock); 对于(i=0;il); //…执行一些可能会将x->data值更改为0的操作 如果(x->o->data==0) 自由(x->o); ReleaseSRWLockExclusive(&x->lock); } void main() { int i; SRWLOCK lock;/*锁在这里*/ object_p object=(object_p)malloc(sizeof(object_t)); 初始化swlock(&lock); /*线程上下文的包*/ 结构 { PSRWLOCK l; 对象(p o),; }上下文={lock,object}; 对于(i=0;i,c,windows,multithreading,winapi,asynchronous,C,Windows,Multithreading,Winapi,Asynchronous,而言,解决方案是不将锁与数据一起分配。我建议您将数据移出该结构,并将其替换为指向该数据的指针。然后,您的链接列表可以先释放数据,然后释放节点,而不会出现任何问题。以下是一些伪代码: /*language C code*/ #include "windows.h" typedef struct object_s { /*change: move lock to stack in main()*/ int data; } object_t, *object_p; /*own an
/*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);
}
作为旁注,Windows C程序永远不能返回void。托管的C程序必须始终返回int。您的程序不会在C编译器上编译 还有,CreateThread()需要一个函数指针,指向返回32位值并以空指针作为参数的函数。如果传递不同类型的函数指针,C中不允许函数指针强制转换,我也不确定如果Windows获得的函数指针与预期的不同,它将执行什么样的疯狂操作。您调用未定义的行为。This可能导致程序崩溃或以意外或随机方式运行
您需要将线程函数更改为
DWORD WINAPI线程(LPVOID参数)
你说得对,现在唯一的办法似乎是让线程阻止对列表的操作,而不是单个节点。我不愿意这样说的原因是我希望多个线程访问列表中的节点,这些节点在线程上下文中已经被引用过,而不必每次都执行迭代n列表。从这个意义上说,线程可能不会引用列表,而只引用节点。通过这样做,我希望争用更少。但现在我意识到这种争用是不可避免的。非常感谢。@Y.Z没有任何东西阻止多个线程访问单个节点,这就是锁存在的原因。“something\u t”在我的示例中,应该是链表节点。我想说的是,您只需将实际数据的分配/释放与链表节点的分配/释放分开,并将锁保留在节点中,而不是与数据一起。
/*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);
}
typedef struct
{
lock_t lock;
int* data_ptr;
} something_t;
void init_something (something_t* thing, ...)
{
thing->lock = init_lock();
thing->data_ptr = malloc(...); // whatever the data is supposed to be
}
void free_something (somthing_t* thing)
{
lock(thing->lock);
free(thing->data_ptr);
thing->data_ptr = NULL;
unlock(thing->lock);
}
...
void linked_list_delete_node (...)
{
free_something(node_to_delete->thing);
free(node_to_delete);
}
...
void thread (void* x)
{
lock(x->lock);
//...do something that could probably change x->data_ptr->data... to 0
if(x->data_ptr->data == 0)
{
free_something(x->data_ptr->data);
}
unlock(x->lock);
}
AcquireSRWLockExclusive(lock);
if(_x->o->data==0)
free(_x);
ReleaseSRWLockExclusive(lock);