进程间同步有哪几种方式?

mmzhzjia 2013-08-26 02:33:18
进程间同步有哪几种方式
...全文
2229 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
lty369963 2013-08-27
  • 打赏
  • 举报
回复
OS书中 有
Defonds 2013-08-27
  • 打赏
  • 举报
回复
计时器、信号量、事件、互斥锁 +1
super_admi 2013-08-26
  • 打赏
  • 举报
回复
俺也来学习学习。
zaixiankaifa 2013-08-26
  • 打赏
  • 举报
回复
这么说是五种了
mmzhzjia 2013-08-26
  • 打赏
  • 举报
回复
进程间的通信(互斥锁、条件变量、读写锁、文件锁、信号灯) 2012-04-20 10:19:39 分类: LINUX 为了能够有效的控制多个进程之间的沟通过程,保证沟通过程的有序和和谐,OS必须提供一定的同步机制保证进程之间不会自说自话而是有效的协同工作。比如在 共享内存的通信方式中,两个或者多个进程都要对共享的内存进行数据写入,那么怎么才能保证一个进程在写入的过程中不被其它的进程打断,保证数据的完整性 呢?又怎么保证读取进程在读取数据的过程中数据不会变动,保证读取出的数据是完整有效的呢? 常用的同步方式有: 互斥锁、条件变量、读写锁、记录锁(文件锁)和信号灯. 互斥锁: 顾名思义,锁是用来锁住某种东西的,锁住之后只有有钥匙的人才能对锁住的东西拥有控制权(把锁砸了,把东西偷走的小偷不在我们的讨论范围了)。所谓互斥, 从字面上理解就是互相排斥。因此互斥锁从字面上理解就是一点进程拥有了这个锁,它将排斥其它所有的进程访问被锁住的东西,其它的进程如果需要锁就只能等待,等待拥有锁的进程把锁打开后才能继续运行。 在实现中,锁并不是与某个具体的变量进行关联,它本身是一个独立的对象。进(线)程在有需要的时候获得此对象,用完不需要时就释放掉。 互斥锁的主要特点是互斥锁的释放必须由上锁的进(线)程释放,如果拥有锁的进(线)程不释放,那么其它的进(线)程永远也没有机会获得所需要的互斥锁。 互斥锁主要用于线程之间的同步。 条件变量: 上文中提到,对于互斥锁而言,如果拥有锁的进(线)程不释放锁,其它进(线)程永远没机会获得锁,也就永远没有机会继续执行后续的逻辑。在实际环境下,一 个线程A需要改变一个共享变量X的值,为了保证在修改的过程中X不会被其它的线程修改,线程A必须首先获得对X的锁。现在假如A已经获得锁了,由于业务逻 辑的需要,只有当X的值小于0时,线程A才能执行后续的逻辑,于是线程A必须把互斥锁释放掉,然后继续“忙等”。如下面的伪代码所示: 1.// get x lock 2.while(x <= 0){ 3. // unlock x ; 4. // wait some time 5. // get x lock 6.} 7.// unlock x 这种方式是比较消耗系统的资源的,因为进程必须不停的主动获得锁、检查X条件、释放锁、再获得锁、再检查、再释放,一直到满足运行的条件的时候才可以。因 此我们需要另外一种不同的同步方式,当线程X发现被锁定的变量不满足条件时会自动的释放锁并把自身置于等待状态,让出CPU的控制权给其它线程。其它线程 此时就有机会去修改X的值,当修改完成后再通知那些由于条件不满足而陷入等待状态的线程。这是一种通知模型的同步方式,大大的节省了CPU的计算资源,减 少了线程之间的竞争,而且提高了线程之间的系统工作的效率。这种同步方式就是条件变量。 坦率的说,从字面意思上来将,“条件变量”这四个字是不太容易理解的。我们可以把“条件变量”看做是一个对象,一个铃铛,一个会响的铃铛。当一个线程在获 得互斥锁之后,由于被锁定的变量不满足继续运行的条件时,该线程就释放互斥锁并把自己挂到这个“铃铛”上。其它的线程在修改完变量后,它就摇摇“铃铛”, 告诉那些挂着的线程:“你们等待的东西已经变化了,都醒醒看看现在的它是否满足你们的要求。”于是那些挂着的线程就知道自己醒来看自己是否能继续跑下去 了。 读写锁: 互斥锁是排他性锁,条件变量出现后和互斥锁配合工作能够有效的节省系统资源并提高线程之间的协同工作效率。互斥锁的目的是为了独占,条件变量的目的是为了 等待和通知。但是现实世界是很复杂di,我们要解决的问题也是多种多样di.从功能上来说,互斥锁和条件变量能够解决基本上所有的问题,但是性能上就不一 定完全满足了。人的无休止的欲望促使人发明出针对性更强、性能更好的同步机制来。读写锁就是这么一个玩意儿。 考虑一个文件有多个进程要读取其中的内容,但只有1个进程有写的需求。我们知道读文件的内容不会改变文件的内容,这样即使多个进程同时读相同的文件也没什 么问题,大家都能和谐共存。当写进程需要写数据时,为了保证数据的一致性,所有读的进程就都不能读数据了,否则很可能出现读出去的数据一半是旧的,一半是 新的状况,逻辑就乱掉了。 为了防止读数据的时候被写入新的数据,读进程必须对文件加上锁。现在假如我们有2个进程都同时读,如果我们使用上面的互斥锁和条件变量,当其中一个进程在 读取数据的时候,另一个进程只能等待,因为它得不到锁。从性能上考虑,等待进程所花费的时间是完全的浪费,因为这个进程完全可以读文件内容而不会影响第一 个,但是这个进程没有锁,所以它什么也做不了,只能等,等到花儿都谢了。 所以呢,我们需要一种其它类型的同步方式来满足上面的需求,这就是读写锁。 读写锁的出现能够有效的解决多进程并行读的问题。每一个需要读取的进程都申请读锁,这样大家互不干扰。当有进程需要写如数据时,首先申请写锁。如果在申请 时发现有读(或者写)锁存在,则该写进程必须等待,一直等到所有的读(写)锁完全释放为止。读进程在读取之前首先申请读锁,如果所读数据被写锁锁定,则该 读进程也必须等待读锁被释放位置。 很自然的,多个读锁是可以共存的,但写锁是完全互相排斥的。 记录锁(文件锁): 为了增加并行性,我们可以在读写锁的基础上进一步细分被锁对象的粒度。比如一个文件中,读进程可能需要读取该文件的前1k个字节,写进程需要写该文件的最 后1k个字节。我们可以对前1k个字节上读锁,对最后1k个自己上写锁,这样两个进程就可并发工作了。记录锁中的所谓“记录”其实是“内容”的概念。使用 读写锁可以锁定一部分,而不是整个文件 。 文件锁可以认为是记录锁的一个特例,当使用记录锁锁定文件的所有内容时,此时的记录锁就可以称为文件锁了。 信号灯: 信号灯可以说是条件变量的升级版。条件变量相当于铃铛,铃铛响后每个挂起的进程还需要自己获得互斥锁并判断所需条件是否满足,信号灯把这两步操作糅合到一 起。 在Posix.1基本原理一文声称,有了互斥锁和条件变量还提供信号灯的原因是:“本标准提供信号灯的而主要目的是提供一种进程间同步的方式 ;这些进程可能共享也可能不共享 内存区。互斥锁和条件变量是作为线程间的同步机制说明的 ;这些线程总是 共享(某个)内存区。这两者都是已广泛使用了多年的同步方式。每组原语都特别适合于特定的问题”。尽管信号灯的意图在于进程间同步,互斥锁和条件变量的意图在于线程间同步,但是信号灯也可用于线程间,互斥锁和条件变量 也可用于进程间。应当根据实际的情况进行决定。 信号灯最有用的场景是用以指明可用资源的数量。比如含有10个元素的数组,我们可以创建一个信号灯,初始值为0.每当有进程需要读数组中元素时(假设每次 仅能读取1个元素),就申请使用该信号灯(信号灯的值减1),当有进程需要写元素时,就申请挂出该信号等(信号灯值加1)。这样信号灯起到了可用资源数量 的作用。如果我们限定信号灯的值只能取0和1,就和互斥锁的含义很相同了 感觉这篇文章有不少错误,高手帮忙看看,我都快被误导了
赵4老师 2013-08-26
  • 打赏
  • 举报
回复
《Windows核心编程》
mmzhzjia 2013-08-26
  • 打赏
  • 举报
回复
问题是进程间同步方式有哪些? 我的目的是想把进程间同步与同线程间同步 、进程间通信区别开。 目前有信号量 和文件锁(文件锁正在查,不懂)两个答案,期望有其他答案
赵4老师 2013-08-26
  • 打赏
  • 举报
回复
《Windows核心编程》 Synchronization Functions The following functions are used in synchronization. CancelWaitableTimer CreateEvent CreateMutex CreateSemaphore CreateWaitableTimer DeleteCriticalSection EnterCriticalSection GetOverlappedResult InitializeCriticalSection InitializeCriticalSectionAndSpinCount InterlockedCompareExchange InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedIncrement LeaveCriticalSection MsgWaitForMultipleObjects MsgWaitForMultipleObjectsEx OpenEvent OpenMutex OpenSemaphore OpenWaitableTimer PulseEvent QueueUserAPC ReleaseMutex ReleaseSemaphore ResetEvent SetCriticalSectionSpinCount SetEvent SetWaitableTimer SignalObjectAndWait TimerAPCProc TryEnterCriticalSection WaitForMultipleObjects WaitForMultipleObjectsEx WaitForSingleObject WaitForSingleObjectEx
赵4老师 2013-08-26
  • 打赏
  • 举报
回复
About Interprocess Communications As computer users become more sophisticated, they demand more power from the applications they use. To meet this demand, developers add more features to the applications, and the applications become larger. Large applications eventually become unmanageable, both from a development standpoint and from a user-interface standpoint. One method you can use to manage larger applications is to produce a specialized application that provides a limited number of features, then enable it to communicate and share data with other specialized applications using some form of IPC. It is not necessary for a single application meet all its users' expectations; applications can communicate and cooperate. The following IPC mechanisms are supported by the Win32 API: Clipboard COM Dynamic Data Exchange (DDE) File Mapping Mailslots Pipes RPC Windows Sockets WM_COPYDATA
mmzhzjia 2013-08-26
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
问题是进程间同步方式有哪些?我是目的是想把进程间同步与同线程间同步 、进程间通信区别开 目前有信号量 和文件锁两个答案
大尾巴猫 2013-08-26
  • 打赏
  • 举报
回复
引用 3 楼 mmzhzjia 的回复:
[quote=引用 1 楼 ananluowei 的回复:] 常用的 : 计时器、信号量、事件、互斥锁 以上4种内核对象配合等待函数。 windows环境。
互斥锁也是吗 感觉互斥锁是线程同步用的[/quote] 线程同步不用互斥锁,代价太大。锁1次是临界区的20倍甚至50倍以上的时间。 线程同步可以用volatile变量、interlocked系列函数、SRW读写锁(vista系统及以上)、临界区 消耗的时间从小到大。这些都只能用于线程同步,不能用于进程同步。 当然线程同步也用到计时器、信号量、时间和等待函数。
mmzhzjia 2013-08-26
  • 打赏
  • 举报
回复
引用 1 楼 ananluowei 的回复:
常用的 : 计时器、信号量、事件、互斥锁 以上4种内核对象配合等待函数。 windows环境。
互斥锁也是吗 感觉互斥锁是线程同步用的
赵4老师 2013-08-26
  • 打赏
  • 举报
回复
大尾巴猫 2013-08-26
  • 打赏
  • 举报
回复
常用的 : 计时器、信号量、事件、互斥锁 以上4种内核对象配合等待函数。 windows环境。
Linux系统提供了各种系统调用API用于进程的通信:    无名管道PIPE    命名管道FIFO    消息队列    共享内存    信号量    文件锁    信号signal....其中还包括system V和POSIX 两种接口标准,除此之外,Linux系统自身还扩展了自己的一套API接口用于进程通信,比如signalfd、timerfd、eventfd等。本视频教程为《Linux系统编程》第05期,本期课程将会带领大家学习Linux下将近15种进程通信IPC工具的使用,了解它们的通信机制、编程实例、使用场景、内核中的实现以及各自的优缺点。本课程会提供PDF版本的PPT课件和代码,学员购买课程后可到课程主页自行下载嵌入式自学路线指导图:------------------------------------------------------------------------------------------------------                   《嵌入式工程师自我修养》嵌入式自学系列教程                                          作者:王利涛------------------------------------------------------------------------------------------------------一线嵌入式工程师精心打造,嵌入式学习路线六步走: 第 1 步:Linux三剑客零基础玩转Linux+UbuntuGit零基础实战:Linux开发技能标配vim从入门到精通基础篇:零基础学习vim基本命令vim从入门到精通定制篇:使用插件打造嵌入式开发IDEmakefile工程实践基础篇:从零开始一步一步写项目的Makefilemakefile工程实践第2季:使用Autotools自动生成Makefile软件调试基础理论printf打印技巧Linux内核日志与打印使用QEMU搭建u-boot+Linux+NFS嵌入式开发环境第 2 步:C语言嵌入式Linux高级编程第1期:C语言进阶学习路线指南第2期:计算机架构与ARM汇编程序设计第3期:程序的编译、链接和运行原理第4期:堆栈内存管理第6期:数据存储与指针第7期:嵌入式数据结构与Linux内核的OOP思想第8期:C语言的模块化编程第9期:CPU和操作系统入门      搞内核驱动开发、光会C语言是不行的!      你还需要学习的有很多,包括:计算机体系架构、ARM汇编、程序的编译链接运行原理、CPU和操作系统原理、堆栈内存管理、指针、linux内核中的面向对象思想、嵌入式系统架构、C语言的模块化编程.....第 3 步:Linux系统编程第00期:Linux系统编程入门第01期:揭开文件系统的神秘面纱第02期:文件I/O编程实战第03期:I/O缓存与内存映射第04期:打通进程与终端的任督二脉第05期:进程通信-------------------we are here!‍    第 4 步:Linux内核编程‍    练乾坤大挪移,会不会九阳神功,是一道坎。搞驱动内核开发,懂不懂内核也是一道坎。第 5 步:嵌入式驱动开发    芯片原理、datasheet、硬件电路、调试手段、总线协议、内核机制、框架流程....第 6 步:项目实战    嵌入式、嵌入式人工智能、物联网、智能家居...

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧