Windows程序设计学习笔记——线程(二)同步
来源:http://www.tudoupe.com时间:2022-07-30
一、同步问题概述
如果多个线程同时读写到相同的变量(内存区),结果将与线程转换的结果(计算机时间表分配)不符,如果两个线程A和B同时执行变量自增操作,因为A从内存数据转换为CPU,然后从线程转换为B,B取完数据,在Cpu操作完成后,结果被写回记忆中,线程被转换为A,A继续从中断位置执行,即计算和写回记忆,这使得A和B返回相同的记忆结果,也就是说,它是一个变量的自增的结果,而不是两个自加操作的结果,这就是同步问题
如图:
运行结果:
用户模式下的解决方案
1.原子(相互锁定)操作
原子操作是未被线程时间表中断的操作,并不会在操作中引起线程开关的操作。窗口提供的原子操作API如下:
以自增运算为例:
演示:
运行结果:
第一个可以看到多次运行的线程的值总是在变化,这是因为在执行这些原子操作时,线程不断交换,所以第一个线程的值总是不固定,但是它总是大于1,00,00,最后的变量是2,00,00,相当于在循环中执行两次
2.临界区
如果我们的操作不是自加,而是如下:
编译后,你会发现它不能运行,并且中断位置没有固定,像这样
原子操作api仅用于简单的操作,当操作更加复杂时,我们可以使用一个关键区域,相当于锁定,锁定代码,只允许当前线程访问,其他线程将被锁定, relatedapi:
进入关键区域(上锁):
参数是一个结构指向下述结构的指针
这个机构的成员不需要由我们填补,而是由我们自己填补
出临界区(开锁):
临界区初始化:
临界区反初始化
示例:
三、内核同步对象
由Windows内核提供,可以使用0环和3环
1.互斥体
与内核版本相符的临界区域可以在整个进程中使用
创建或打开互斥体:
注意,如果第二个参数是 TRUE,并且调用者创建了相互锁,调用者线程获得相互体的初始所有权
补充:虽然每个过程都有自己的独立资源和空间,但是有时候,我们只是需要这个程序在系统上保存一个进程的实例,这就是过程互惠的问题。CreateMutex函数的第三个参数可以指定对象的名称,每次一个程序运行时,系统是否存在同一个名称的相互厌恶对象,以确定该程序是否重复运行。如果有相同名称的对象,GetLastError()函数返回 ERROR_ALREADY_EXISTS
锁定相互对象(同样用于等待一个线程或进程结束):
如果互斥体未锁上,则该函数将上锁,否则将处于阻塞状态,第二个参数表示超时时间,如果过了这个时间,锁仍然未开,则函数将退出,但是如果这个时间内锁开了,函数也会退出,可以根据返回值来判断是哪种情况退出:
WAIT_OBJECT_0 |
锁开了 |
WAIT_TIMEOUT |
锁未开,超时了 |
WAIT_ABANDONED |
确定使用相互厌恶实体的线程是否终止 |
解锁(将线程的控制权释放到相互排除的对象):
示例:
关键区域与相互厌恶的机构之间的区别:
对于互斥体来说,当上锁的线程结束了并且没有开锁,锁会自动开,这种开锁称为线程遗弃,而对于临界区,当上锁的线程结束了并且没有开锁,锁不会自动开,其他线程依然处于阻塞状态
2.事件
创建事件内核对象:
第二个参数确定是否自动解锁,或者是否调用api来解锁自己
第三个参数表明您不应该解锁初始状态
上锁/等待:
锁定(设置事件对象触发):
上锁(将事件对象设置为未触摸):
示例:
3.信号量
信号数量和前面的临界区域,相互厌恶等等,都是不同的,临界区,复合是专用CPU资源,信号数量用于限制同时运行的线程数目。信号量内核对象中有一个最大资源计数和一个当前资源计数,最大资源计数表示信号量可以控制的最大资源数目,当前资源计数表示当前资源可用信号的数目。
创建信号量:
增加信号个数:
如果当前资源计数大于0,那么信号量处于触发状态,如果当前资源计数等于0,那么信号量处于未触发状态。当一个线程访问资源时,当前资源计数会减一,但是当前资源计数一定大于等于0并且小于最大资源计数
使用:
运行结果:
补充:
对线程同步来说,每个核对象有两个状态,要么处于触发/有信号(signaled)状态,要么处于未触发/无信号(nonsignaled)状态,每种对象都有相应规则在这两个状态中切换,如果进程内核对象在创建时总是处于未触摸的状态,当进程终止时,该进程的内核对象由操作系统设置为触发状态。对于线程来说,如果线程等待的对象处于未触摸的状态,在这一点上,这条线是不可逆转的,当对象处于触发状态时,只有线程可以转换为模块化,上述WaitForSingleObject函数是一个等待函数,将允许一个线程单独进入等待状态,直到指定的内核对象被触发或在一段时间内.
锁实际上是一个等待对象被触发的线程,然后被锁定,打开锁是为了让对象被触发
等待多个对象可以调用下列API:
上一篇:秒杀项目的总结及面试常见问题
下一篇:学位英语考试常见问题解答!
相关新闻
- 2023-04-16 2台电脑怎么共享(2台电脑怎么共享
- 2023-04-16 主板检测卡代码(电脑主板检测卡代
- 2023-04-16 dnf未响应(dnf未响应老是上不去)
- 2023-04-16 ppoe(pppoe拨号上网)
- 2023-04-16 网速不稳定(网速不稳定是路由器的
- 2023-04-16 wds状态(Wds状态成功)
- 2023-04-16 光标键(光标键不动了怎么办)
- 2023-04-16 电脑提速(电脑提速100倍的方法)
- 2023-04-16 切换用户(切换用户怎么切换回来
- 2023-04-16 数据包是什么(产品数据包是什么
|
|
|
|
|
|
|
|
|
|