//自旋锁*******************************************************************************************************
/*多线程问题用到的,比如,在内核环境下操作一个全局链表,一个线程在操作的时候发生了切换到另一个线程
也来操作这个链表,那前一个线程还没操作完,换到另一个线程来操作会怎样?通常要么这个链表丢失了,要么损坏了。
所以需要一个锁来控制,当前一个线程在操作的时候他得到一个锁,这个锁唯一的,如果他没操作完就不释放出来,其他线程如果
没有得到这把锁就无法操作,直到这个线程操作完了把锁释放出来,其他线程就能得到这个锁,得到了锁就能操作,这样就能完成
同步问题。
1.如何获得并初始化一个自旋锁***********************************************************************************
KSPIN_LOCK my_spin_lock; //声明一个自旋锁
KeInitializeSpinLock(&my_spin_lock);//将自旋锁初始化。
2.如何使用自旋锁***********************************************************************************************
KIRQL irql;用于保存中断级别
KeAcquireSpinLock(&my_spin_lock,&irql);这个函数会提高中断级别。就得中断级别被保存在上一行声明的变量里。
//这里做点事情。
KeReleaseSpinLock(&my_spin_lock,irql);释放锁,回复中断级别。
需要注意的是:
KSPIN_LOCK my_spin_lock;
KeInitializeSpinLock(&my_spin_lock);
尽量声明在静态变量,全局变量里。如果声明在某个函数里,随着函数执行的结束,声明的变量的声明周期也就结束了。
这样多线程锁就起不到"锁"的作用。声明在全局变量中,多个线程共用同一把锁,才能起到"锁"的作用。
3.自旋锁在链表中的使用****************************************************************************************
可以这么写
LIST_ENTRY list_entry_head; //声明一个链表头
KSPIN_LOCK list_entry_lock; //声明一个自旋锁
void ListInitialized()
{
InitializeListHead(&list_entry_head);//初始化链表头
InitializeListSpinLock(&list_entry_lock);//初始化自旋锁
}
然后在操作链表的函数中,多传入一个锁的指针参数,在操作链表之前先KeAcquireSpinLock,然后操作完之后
再KeReleaseSpinLock
*/