存档

‘操作系统’ 分类的存档

用于线程同步的读写锁(Readers/writer locks)

2010年2月21日 没有评论

  读写锁(readers/writer lock)的具体含义是文如其名:对一个资源有多个读者而无写入者,或者是只有一个写入者而没有其他的写入者或读出者。

  这种情况是经常会用到的,这就需要有一种专用于这个目的的特殊的同步元素。

  很多情况下,你需要有个数据结构在一堆线程之间共享。当然,你希望在一个时刻只能有一个线程可以对这个数据结构执行写入操作。如果同时有多个线程能对其写入,那么就有可能一个线程写入的数据会覆盖其他线程所写入的数据。为了防止这种情况发生,写线程可以用独占的方式获取“读写锁”,也就是说只有它才能够访问这个数据结构。不过需要注意这个访问的独占性严格受控于随意的方式。也就是说这是由系统设计者来处理的,是由系统设计者来确保所有访问那个数据区域的线程通过读写锁进行同步。

阅读全文…

互不关联的多线程

2010年1月28日 没有评论

  我们在前面曾经说过,当多个互相独立的处理算法对同一个共享的数据结构进行处理的时候使用多线程是有用的。严格地说你也可以使用多个进程(每个进程有一个线程)来共享数据,有些情况下使用同一个进程中的多个线程来处理会更简单些。下面说说在哪里以及为什么要使用多线程。

  我们的例子里,我们会使用一个标准的输入/处理/输出的模型。通常来说,这个模型的一部分负责从什么地方获取输入,另外一部分负责处理输入并产生某种形式的输出,第三部分则是将输出反馈到什么地方。

多进程

  先来看看多进程、每个进程一个线程的情况。在这里,我们有三个进程,一个输入进程、一个处理进程和一个输出进程,如下面的示意图所示:

阅读全文…

在SMP系统使用多线程需要注意的事情

2010年1月28日 没有评论

  尽管你一般可以忽略你的系统是运行在SMP架构上还是单处理器上,不过还是有些事情会影响到你。不幸的是,这些事情都是低概率事件,它们可能在你的开发阶段没有出现,但是可能在测试、演示或更糟的,在实际应用中出现。在编程的时候花些时间做些防御性的措施可以在后续的阶段减少问题的发生几率。

  下面就是你可能在SMP系统上遇到的事情:

  • 多个线程确实可以也能同时运行——不过依赖于像FIFO调度、优先级这些东西来同步是不允许的;
  • 多线程可与中断服务程序(ISR)同时运行——也就是说你不但要保护线程不受ISR的影响,也要保护中断服务程序不受线程的影响;
  • 有些操作你期望是最小单元的、单步的,可能会依赖于操作与处理器的不同而不是最小单元的、单步的。这类的操作包括了需要“读取-修改-写入”周期操作的(例如:++,–,|=,&=等等)。你可以查找<atomic.h>文件来查找对应的最小单元替换函数。(这也不是只有SMP系统的问题,大多数的RISC处理器对上面的胆码也不是按照最小单元处理的)

在单CPU上使用多线程

2010年1月27日 没有评论

  假设我们略微修改我们的例子,让它能演示有些时候在单处理器上使用多线程的好处。

  在这个修改的例子里面,网络中的一个节点负责计算扫描线(与前面的图像例子一样)。不过,当一个扫描线的计算结束后,它的数据就通过网络发送到另外一个节点。下面是我们修改后的main()函数:

阅读全文…

多线程中壁垒(barrier)的使用

2010年1月27日 没有评论

  前面我们讲过main()函数与工作线程结束进行的同步,在那里提到了两种方式:pthread_join()函数以及壁垒(barrier)。

  现在我们回到房子的比喻,假设这个家庭准备到哪个地方旅行。司机上了小货车并发动了引擎。之后,司机就开始等待。只有全部的家庭成员都上车之后,这个小货车才会开动——因为我们不想把任何人落下!

  这和我们在前面说的那个绘图程序的原理是一模一样的。主线程要等待全部工作线程结束后,才执行下一步的程序。

  不过和这个比喻还有一个很大的差别。那就是通过使用pthread_join()函数,我们是等待所有工作线程的结束。也就是说,之后这些线程已经不存在了,它们退出了。

阅读全文…