您的位置:首页 > 其它

基于内核对象的一种多线程同步机制的本质

2015-09-02 16:21 197 查看
多个处理器的CPU高速缓存间设计的硬件级别的(读写)同步规则:

同时一个写多个读:一个CPU写后通知其他CPU将各自CPU高速缓存上的数据作废重新读取内存上值来覆盖之

同时多个写,则估计要用软件级别的同步机制规则来搞定了。

源代码里的(如函数参数)变量地址值形式(*(&a))要求每次调用该参数时都去读取一次内存上该变量的值,而(如函数参数)变量形式则可以不必要求每次调用该参数时都去读取一次内存上该变量的值而是用CPU高速缓存上该变量已有值即可

=======================

自动设置事件和人工设置事件的区别:

自动设置事件触发后,操作系统会随机唤醒一个等待该自动设置事件的线程,使之处于可调度状态;

人工设置事件触发后,操作系统会唤醒所有等待该自动设置事件的线程,使之处于可调度状态;

两者为什么会有如此差别?
因为

执行如waitforsingleobject函数的那一个系统进程A,有一个为waitforsingleobject函数创建的(先进先出的)队列C来存放那些调用了waitforsingleobject函数的应用程序线程以及其等待的内核对象,所以该队列的一个节点的数据结构里含有调用了waitforsingleobject函数的应用程序线程ID以及其等待的内核对象的地址信息。

假设现在有三个线程先后调用了waitforsingleobject函数来等待同一个事件内核对象B,则为waitforsingleobject函数创建的(先进先出的)队列里就先后进了三个节点。

当三个线程先后调用了waitforsingleobject函数来等待的同一个事件内核对象B为人工设置事件时,如果操作系统检查到事件内核对象B(在另一个队列里?用于为执行如waitforsingleobject函数的那一个系统进程A存放各种内核对象,每隔一段时间来遍历一次该队列而能判断其中哪些对象被触发了)的状态为触发状态,则执行waitforsingleobject函数的那一个系统进程A就会去遍历一次队列C,遍历过程中发现了上述三个节点中的任一个节点时所做的事情为:

1、唤醒该节点里提到的线程

所以一次遍历后就会遍历到上述三个节点,所以就会唤醒三个线程。

当三个线程先后调用了waitforsingleobject函数来等待的同一个事件内核对象B为自动设置事件时,如果操作系统检查到事件内核对象B(在另一个队列里?)的状态为触发状态,则执行waitforsingleobject函数的那一个系统进程A就会去遍历一次队列C,遍历过程中头一回发现了上述三个节点中的任一个节点时所做的事情为:

1、唤醒该节点里提到的线程

2、修改该节点里提到的事件内核对象B的状态为未触发状态

所以一次遍历后遍历到第二个第三个节点时就不会唤醒这两个线程(或者遍历到第一个节点修改了事件内核对象B的状态为未触发状态后就直接退出该队列而不遍历到队列尾部),因为此时事件内核对象B的状态已经在第一个节点时该为未触发状态。未触发状态,自然就不用线程了。

这里看到一个系统进程和其一个队列的模式实现了基于内核对象的一种多线程同步机制。这就是基于内核对象的一种多线程同步机制的本质。

三个线程先后调用了waitforsingleobject函数来等待的同一个事件内核对象B时,若事件内核对象B的状态处于为未触发状态,则三个线程会被挂起。

========

如果基于内核对象的一种多线程同步机制的本质为

三个应用程序线程 对应 三个系统线程

系统线程为了检查内核对象状态和修改内核对象状态两个步骤成为原子操作,而采用了类似于用户态模式时的同步机制(如interlock函数系列),则基于内核对象的一种多线程同步机制的本质和用户态模式时的同步机制就没有区别。所以,这一模式猜想(对基于内核对象的一种多线程同步机制的本质)不对.

============

同步代码+同步锁变量(即该变量业务逻辑上充当锁的作用)=同步机制

==================

参见
《Windows核心编程 第五版》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: