`
leogao_emcom
  • 浏览: 82976 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

OS是如何实现多线程情况下的同步机制的。

阅读更多

Java,C#,C/C++等等的高级语言,无论是平台独立语言java/C#等,还是非独立的,如C/C++等,它们最终的代码都要有CPU和OS内核的进程和线程调度机构来执行的(对于java/C#这样的语言来说,很多人认为是在JVM/CLR这样的虚拟机上运行的,其实是有错误的,更加准确的说是,JVM/CLR提供了一种原语,比如bytecode/MSIL,当其编译时,由编译器将高级语法编译成bytecode/MSIL,然后JVM/CLR将这些高层的“汇编”翻译成二进制代码(JIT干的事情),这些二进制代码才是真正的可以执行的指令,这些指令时以线程的形式被调度给CPU执行的,所以根本上而言线程的问题和机能都是CPU和OS共同实现的事情,而不是什么java/C#等等它们自己实现的事情,只是提供了高层的表述,所以一旦理解CPU和OS是如何实现多线程条件下是如何实现同步机制的,那么也就找到了源头,对理解和使用java/C#等的多线程编程方式就比只停留在高级语言层面的理解要准确的多,甚至于可以自己开发更加高效的多线程例程库或者并发库,java 1.5以后增加的并发包是由一位教授实现的,其实也是在充分理解了OS这种实现,能够知道什么地方最优化,采用什么算法才能充分利用底层这种实现而设计和实现出来的。对个我们这些软件开发人员而言,有时间去了解一些底层的工作原理对从事的工作也是很有好处的,虽然我们直接用不上,但是我们常常间接的在用。

 

OS是这样做的,拿Window为例,由于多处理器、多核或者中断等(中断是调度线程的基本方式,当一个正在运行的线程被一个中断信号中断,那么CPU就会被其他线程接手,轮换的进行执行,CPU分给一个线程时间片类执行,因为CPU很快,所以人的眼睛看起来就像是多个任务同时执行似的)各种并发性因素存在,同样的代码可能被并发的执行,而数据也可能被并发的访问,这种情况下,比如一个共享的变量很可能就被一个中断而接手的线程修改覆盖其值,照成不一致的情况发生,这在金融或者在线交易型的一些系统表现明显,如果用户存入数据库中钱数被其他用户的线程给修改了,这是很可怕的事情!CPU和OS利用中断来调度线程时,是利用一种叫做IDT(中断描述表)的东西来实现的,IDT中将每一个中断和一个中断处理程序对应起来,也就是说一旦一个中断发生,OS就会去找对应的另外一个程序来处理,这样就停止了当前的线程而将CPU交给另外一个,OS在实现的时候自己也定义了一个软中断表,并且为中断定义了优先级0-31,其中0最低,0-2是软件可以使用的中断,其他是硬件中断,那么OS是这样使用优先级的,越高级的中断越不会被打断!那么OS如果提升当前线程的优先级,那么它就很不容易打断,此时可以保证一致性,但是由于调度器的存在,最终还是会被打断的,不可能长时间不给其他线程执行的机会!

 

所以提升中断优先级的作法只是一种一般作法,并不能从根本上解决问题。所以下面衍生出来很多其他的办法:

1)互锁操作:利用CPU的lock指令,锁住,也就是排除其他线程占有一个变量(变量进入寄存器后,CPU说了算),那么

这个变量就得到了同步保护!

2)自旋锁:提升其中断优先级,让它的执行体只是执行一个什么也不干的空循环,也就是它的状态总是等待的,那么CPU

也是空闲的,空转!其他线程也得不到它,那么可以解决调度器会自动降低优先级而使其他线程得到控制权的问题,那么一个线程处于等待它就不会去扰乱别人了,而且不会像第一种方法那么强势,所以很多非锁定算法使用了自旋锁的办法。

那么如何解除等待,又衍生出了很多有趣的东西,OS有一种等待块的数据结构,其实就是一个用来解除自旋状态的装置,它依靠信号才解除自旋,开和关的信号,关就是等待中,开就是解除等待,就像是交通的红绿灯,也就是说自旋状态必须使用信号显式的解除,高级语言都提供这样的东东,不过也都是OS底层实现的:

1)事件:一个事件的到来,而解除等待的状态

2)突变体:mutex,如果其是无信号的状态,那么线程就一定是占有它的,那么调度器就认为此线程应该自旋等待,否则就解除自旋等待状态,通常高级语言利用这个玩意实现“锁”的机制,这个锁不同于CPU的lock锁,是轻量级的,是程序可控的,就是通过程序代码发出信号来控制的,比如读写锁对象的lock和unlock方法,它们发布信号通知突变体改变其状态。一旦一个线程处于自旋等待,那么它就没有机会去修改一个变量的值,那么当前线程就不会因为被打断而变量被其他线程而修改覆盖了!这是同步机制实现的最基本办法!也是理解好什么事同步,什么是竞争条件,以及什么是线程安全概念的核心,这对理解好高级语言中的多线程问题很有帮助,也催生出各种数据结构来使用突变体,比如java 1.5并发包中的那些东西。

3)信号量:也就是semaphore,所以称量,也就是信号的数量,理解了突变体就很好理解什么是量!也就是给信号计数,

加或者是减,当计数到一个指定值时再发出一个开或者关的信号,那么其实就突变体的衍生和加强。

4)队列对象:一种数据结构,让线程在其中排队,排着队去占有一个变量或CPU时间

5)进程对象:当创建的时候是无信号的状态,当进程结束时是有信号的状态,这是很多程序的行为模式,比如调用一个程序时,只有等这个程序干完了活,自己才可以接着干自己的,这种情况司空见惯!但是还是突变体的用法创新而已。

6)线程对象:也是一种数据结构,这种情况也很平常,比如一段代码调用一个子程序或者子方法,必须等待子方法完成执行,自己才能接着执行。也就是创建线程的时候是无先好,线程销毁时是有信号!这是我们写程序是天天看到的东东。

7)定时器对象:计时器,没有到设定的时间时是无先好,到了时间就是有信号,看,也是突变体的变体!

其他就不介绍了,看,基本都是利用信号这种东东实现了这么多东西。从理解信号和突变体出发,就可以理解好其他的解决办法,理解好这些办法,就能更加灵活的使用那些高级语言提供的同步语法(比如java 1.5的并发包),甚至于发明更加好的同步和并发算法和实现。

 

所以研究OS内核的意义不在于我们去创造一个新内核,而是利用现有的原理更好的使用我们手中的工具!

0
0
分享到:
评论

相关推荐

    Objective-C高级编程 iOS与OS X多线程和内存管理

    《Objective-C高级编程:iOS与OS X多线程和内存管理》是一本深入探讨Objective-C在iOS和OS X平台上的核心特性的书籍。本书重点聚焦于多线程和内存管理两个关键领域,对于iOS和macOS应用开发人员来说,这是理解和优化...

    ACE线程、锁、同步机制

    ACE(Adaptive Communication Environment)是一个轻量级的OS并发机制的OO封装,旨在提供一种可移植和可扩展的接口,简化开发者在多种平台上开发客户和服务器应用时的线程管理和同步机制。ACE线程封装库的设计目标是...

    windows系统的多线程同步实验报告和cpp

    在Windows系统中,有多种实现多线程同步的方法: 1. **临界区(Critical Section)**:临界区是一种简单而有效的同步机制,它允许一次只有一个线程进入特定的代码段(即临界区)。这样可以确保在任何时候只有一个线程...

    Objective-C高级编程 iOS与OS X多线程和内存管理_Objective-C_ios_

    此外,书中的内容可能还包括线程同步和线程安全问题,如锁(NSLock、@synchronized关键字)、信号量(NSCondition)、GCD的同步队列等,这些都是避免多线程环境下数据竞争的重要工具。同时,内存管理部分还会涉及弱...

    多线程 定时器 同步 LINUX

    总之,理解和掌握多线程、定时器以及同步机制对于开发高效、稳定的软件至关重要。在C++中,利用标准库可以方便地实现这些功能,同时要注意不同操作系统下的兼容性问题。通过阅读和分析`OSLib_Linux`这样的库,我们...

    IOS线程管理,线程同步

    线程同步是为了防止多线程访问同一资源时出现数据竞争问题。在iOS中,有多种同步机制可供选择: 1. **锁(Locks)**:如NSLock、OS_dispatch_lock等,当一个线程获得锁后,其他线程必须等待释放锁才能继续执行。...

    iOS线程同步方案

    互斥锁是一种最基础的线程同步机制,用于保护共享资源不被多个线程同时访问。在iOS中,我们可以使用`NSLock`类来实现互斥锁。当一个线程获取了锁之后,其他试图获取该锁的线程将会被阻塞,直到持有锁的线程释放锁。...

    OS大作业生产者消费者同步问题的实现

    本大作业旨在让学生理解并熟练运用POSIX提供的同步机制,特别是互斥锁和条件变量,来解决这个问题。以下是相关知识点的详细说明: 1. **互斥锁**:在多线程环境中,互斥锁用于保护共享资源,确保同一时间只有一个...

    多线程编程中英文对照.rar

    9. **异常处理与线程**:在多线程环境下,异常处理需要特别注意,因为异常可能会在任何线程中抛出。了解如何在多线程程序中正确地捕获和处理异常是非常重要的。 10. **资源管理**:在多线程环境中,资源的分配和...

    多线程统计多个文件的单词数目

    5. **线程同步**:在多线程环境下,当各线程需要访问共享资源(如结果集合)时,可能需要线程同步机制,例如Java的`synchronized`关键字、锁(Lock)或者Python的`threading.Lock`,防止数据竞争问题。 6. **性能...

    跨平台(Windows/Linux)多线程同步设施

    综上所述,跨平台的多线程同步设施涉及事件、信号量和互斥锁等多种同步机制,以及平台选择的适配层,这些都是保证多线程程序正确性和效率的关键。理解和熟练运用这些概念对于开发高效、可靠的跨平台软件至关重要。

    QNX环境下多线程编程

    QNX提供了多种同步机制来保证多线程程序的安全、可靠,如pthread_mutex_lock()、pthread_mutex_unlock()、pthread_cond_wait()、pthread_cond_signal()等。这些函数可以用于线程间的同步,以确保多线程程序的安全和...

    uc/os-iii在stm32上面多线程的demo

    这个标题提到的"uc/os-iii在stm32上面多线程的demo"是一个示例项目,展示了如何在STM32F103微控制器上运用UC/OS-III实现多线程处理。STM32F103是意法半导体(STMicroelectronics)的一款基于ARM Cortex-M3内核的32位...

    操作系统课程设计打包奉上【含DOS下多线程的实现,内存模拟文件系统】

    在标题提到的DOS环境下,虽然其原生支持单任务,但通过编程技术可以实现多线程的效果。C语言本身并不直接支持多线程,但可以通过库函数如POSIX的pthread库或Windows API中的CreateThread函数来实现。TURBO C编译器...

    完整版多线程模块.rar

    这个“完整版多线程模块.rar”文件很可能包含了关于如何在不同的编程语言或环境中实现多线程技术的详细教程、示例代码和相关资源。在这个压缩包中,我们可以期待找到与以下知识点相关的内容: 1. **线程基础**:...

    Symbian OS:线程编程中文版

    3. **同步与互斥**:在Symbian OS中,互斥锁(Mutexes)和事件对象(Event Objects)是实现线程同步的主要手段。互斥锁确保同一时间只有一个线程访问特定资源,而事件对象可以用来阻塞线程直到特定事件发生。 4. **...

    ARM多线程应用程序设计

    在ARM处理器上实现多线程,通常会用到操作系统提供的线程管理机制,例如Linux内核的pthread库或者实时操作系统(RTOS)如FreeRTOS、uC/OS等。这些库提供了创建、同步、销毁线程等功能,开发者可以通过API调用来实现...

    多线程编程 从入门到精通

    这使得程序能够更高效地利用计算资源,提高并发性和响应速度,尤其是在多核CPU环境下,多线程能实现真正的并行执行。 **线程的基本概念**: 1. **程序**:由计算机语言编写的静态代码。 2. **进程**:程序在执行时...

Global site tag (gtag.js) - Google Analytics