LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: luckyrex

多线程,如何保证一段代码不被打扰的执行完?

[复制链接]
发表于 2005-9-22 17:01:58 | 显示全部楼层
Post by luckyrex

  其实这个“临界区”是我从uCOS中借用的词,可能不准确。我想表达的意思就是在这个区域内,代码的执行不会被打断。

孤陋寡闻了,不会被打断我们一般称之为"原子操作"

如果只能用开关中断的话,请教一下如何实现?谢谢


开关中断不是一个好办法,不过没有想到更好的办法.
如果实在要用,只能用汇编指令了.不同的cpu有不同的开关中断的指令,x86 为cli/sti
回复 支持 反对

使用道具 举报

发表于 2005-9-22 17:33:19 | 显示全部楼层
哦,原来是我没看明白,确实mutex达不到要求

可是,什么情况下有这种需求呢?
回复 支持 反对

使用道具 举报

发表于 2005-9-22 17:41:29 | 显示全部楼层
开关中断在x86的保护模式下为特权指令,只能由运行在ring0的代码使用,所以要是在用户空间使用可能比较困难。
想到了一种方法,可能不太有效率,就是在执行这段代码之前,把所有其他的线程挂起,确定其他线程已经被挂起之后执行,运行结束后在恢复其他线程的正常运行状态。应该有这种函数吧。
回复 支持 反对

使用道具 举报

发表于 2005-9-22 19:27:01 | 显示全部楼层
Post by gamedragon
开关中断在x86的保护模式下为特权指令,只能由运行在ring0的代码使用,所以要是在用户空间使用可能比较困难。

我也怀疑过这个问题,但是参考了一些资料,并没有提到开关中断是特权指令
IA-32 Intel® Architecture Software Developer's Manual -- v3.System Programming Guide 中提到的 PRIVILEGED INSTRUCTIONS 并没有开关中断指令,不知gamedragon兄从何得知?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-9-22 19:45:17 | 显示全部楼层
Post by rickxbx
孤陋寡闻了,不会被打断我们一般称之为"原子操作"

多谢rickxbx!你现在说我想起来这个词了,呵呵,发贴子的时候忘了。


gamedragon:
    将其他线程挂起的确是个办法,不过我也不知道什么函数能做到。另外,临时提高主线程的优先级,降低其他线程的优先级,估计也可以,不过也不是最理想的。
回复 支持 反对

使用道具 举报

发表于 2005-9-22 19:48:29 | 显示全部楼层
Post by luckyrex

正如我上个帖子说的,如果用mutex锁,因为我不知道CPU切换到另一个线程时,是从其他线程的哪
个地点进入的!有可能切换到其他线程的任何一句代码开始执行。除非我在其他线程的每句代码后面
都写一句访问mutex的代码,把其他线程挂住!不过这种做法显然是不现实的。

也许是我还没想清楚,请各位指点!

怎么会这样呢?
如果用mutex锁,那就只有一个线程能访问共享的数据结构,其它的线程就只能等待这个线程解锁。就算此时cpu切换到另一个线程运行,这些线程的状态仍然是不变的。等待解锁的线程继续等待,唯一取得共享数据结构访问权限的线程照样继续访问共享数据结构。这个mutex锁实际上是一个全体线程的同步点,迫使并发的线程在访问共享数据时串行化。
回复 支持 反对

使用道具 举报

发表于 2005-9-22 20:44:13 | 显示全部楼层
Post by luckyrex
将其他线程挂起的确是个办法,不过我也不知道什么函数能做到。另外,临时提高主线程的优先级,降低其他线程的优先级,估计也可以,不过也不是最理想的。

这个是不可以的,提高优先级无法保证其他线程不执行,用户态是无法预知内核态的工作情况的。
Post by rickxbx
我也怀疑过这个问题,但是参考了一些资料,并没有提到开关中断是特权指令。

我是差不多10年前看的80386的手册,印象中sti/cli是特权指令,就像in/out一样,否则用户程序把中断一关,或者往端口乱写东西,操作系统还有什么搞头啊!或者rickxbx老兄看的是VMode(好像叫这个名字)下面的sti/cli,这种情况下可能是不是特权指令,但是在这种模式下即使执行了cli,底层中断还是照常接受的吧。
回复 支持 反对

使用道具 举报

发表于 2005-9-22 21:44:00 | 显示全部楼层
Post by gamedragon

我是差不多10年前看的80386的手册,印象中sti/cli是特权指令,就像in/out一样,否则用户程序把中断一关,或者往端口乱写东西,操作系统还有什么搞头啊!或者rickxbx老兄看的是VMode(好像叫这个名字)下面的sti/cli,这种情况下可能是不是特权指令,但是在这种模式下即使执行了cli,底层中断还是照常接受的吧。


1. in/out 并非特权指令,eflags寄存器中有两个bit表示iopl,如果当前任务比iopl特权级高,则i/o可执行;

2. VMode 你指的是虚拟86模式吧? 我对虚拟86模式不熟,这个模式下也有特权指令的问题吗? 你可以参看我提到的那份文档,我所说并不是虚拟86模式下情况
回复 支持 反对

使用道具 举报

发表于 2005-9-23 10:02:59 | 显示全部楼层
Post by rickxbx
1. in/out 并非特权指令,eflags寄存器中有两个bit表示iopl,如果当前任务比iopl特权级高,则i/o可执行;

原则上是这样,因为x86架构里有4层ring;但是在普通操作系统(我所知所有的)里,所有代码只有2个运行级别,0(内核)跟3(用户),这是为了兼容性考虑,因为不是所有的CPU架构都有4个级别。所以一般in/out之类的指令在95以后操作系统里都不好随便用的,一般都是通过构造一个中断去切入ring0,然后再使用这些指令。当然95、98里想用in/out更简单,因为保护的差;NT之后的就要复杂一点了。

Post by rickxbx
2. VMode 你指的是虚拟86模式吧? 我对虚拟86模式不熟,这个模式下也有特权指令的问题吗? 你可以参看我提到的那份文档,我所说并不是虚拟86模式下情况

If protected-mode virtual interrupts are not enabled, CLI clears the IF flag in the EFLAGS register. No other flags are affected. Clearing the IF flag causes the processor to ignore maskable external interrupts. The IF flag and the CLI and STI instruction have no affect on the generation of exceptions and NMI interrupts.
When protected-mode virtual interrupts are enabled, CPL is 3, and IOPL is less than 3; CLI clears the VIF flag in the EFLAGS register, leaving IF unaffected.
用这个指令还是有限制的,而且还提到了个VIF flag。所以说如果什么人都可以用sti/cli,那操作系统不就太容易崩溃了,因为最基本的调度都是基于时间中断的。这个中断一被禁止,操作系统基本就处于不活动状态了。
回复 支持 反对

使用道具 举报

发表于 2005-9-23 12:53:41 | 显示全部楼层
Post by gamedragon
原则上是这样,因为x86架构里有4层ring;但是在普通操作系统(我所知所有的)里,所有代码只有2个运行级别,0(内核)跟3(用户),这是为了兼容性考虑,因为不是所有的CPU架构都有4个级别。所以一般in/out之类的指令在95以后操作系统里都不好随便用的,一般都是通过构造一个中断去切入ring0,然后再使用这些指令。当然95、98里想用in/out更简单,因为保护的差;NT之后的就要复杂一点了。


从你的叙述中并没有看出in/out属于特权指令,只是一般情况下是在0特权级下使用.

If protected-mode virtual interrupts are not enabled, CLI clears the IF flag in the EFLAGS register. No other flags are affected. Clearing the IF flag causes the processor to ignore maskable external interrupts. The IF flag and the CLI and STI instruction have no affect on the generation of exceptions and NMI interrupts.
When protected-mode virtual interrupts are enabled, CPL is 3, and IOPL is less than 3; CLI clears the VIF flag in the EFLAGS register, leaving IF unaffected.
用这个指令还是有限制的,而且还提到了个VIF flag。所以说如果什么人都可以用sti/cli,那操作系统不就太容易崩溃了,因为最基本的调度都是基于时间中断的。这个中断一被禁止,操作系统基本就处于不活动状态了。


同样,这段描述也并没有看出cli/sti是特权指令.他只是通过某种手段(比如设置vif位)使cli/sti这样的指令在3特权级下不可用,但这并不代表cli/sti就是特权指令.

最后,并不是说在用户态不可用就是特权指令,也不是说不是特权指令就能在用户态下使用.
限制和特权指令是两回事,不能混为一谈
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表