互不关联的多线程

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()函数,我们是等待所有工作线程的结束。也就是说,之后这些线程已经不存在了,它们退出了。

阅读全文…

线程的启动

2010年1月18日 行者 没有评论

  任何线程在同一个进程中都可以创建另一个线程,这没有任何的限制。创建线程最常用的就是POSIX函数pthread_create(),该函数的定义如下:

#include <pthread.h>

int
pthread_create (pthread_t *thread,
                const pthread_attr_t *attr,
                void *(*start_routine) (void *),
                void *arg);

  函数pthread_create()有四个参数:

  thread  一个指向pthread_t的指针,在那里保存着线程的ID;

阅读全文…