Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1427897
  • 博文数量: 842
  • 博客积分: 12411
  • 博客等级: 上将
  • 技术积分: 5772
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-14 14:43
文章分类

全部博文(842)

文章存档

2013年(157)

2012年(685)

分类: 系统运维

2012-05-14 14:39:47




一个典型的UNIX进程可以被视为单线程控制:每个进程一次只做 一件事。有了多线程控制,我们可以设计我们的程序来在单个进程内同时做多件事,每个线程处理单个任务。这种方式可以有多种好处。


1、我们可以简化处理异步事件的代码,通进为每个事件类型分配一个线程。每个线程可以使用同步编程模型来处理它的事件。一个同步编程模型比一个异步的要简单得多。


2、多个进程必须使用由操作系统提供的复杂机制来共享内存和文件操作符,如我们将在15章和17章看到的。另一方面,线程自动拥有相同内存空间和文件描述符的访问。


3、一些问题可以被分割,以便整个程序的生产力可以被提升。有多个任务的单个进程隐式地序列化执行那些任务,因为只有一个线程控制。有了多进程控制,独立任务的处理可以交叉,通过给每个任务分配一个线程。只当不依赖于对方执行的处理时,两个任务才能交叉。


4、相似地,交互式程序可以提升响应时间,通过多线程来分开处理用户输入输出的部分和程序的其它部分。


一些人把多线程编程关联到多处理器系统。即使你的程序在单处理器上运行,一个多线程编程模型的好处也可以得到体现。一个程序可以用线程简化,而不管处理器的 数量是多少,因为处理器的数量不会影响程序结构。更甚,只要你的程序在序列化任务时必须阻塞,你就仍可以看到响应时间和运行在多处理器上时的生产力的提 升,因为一些线程可能可以在别的线程阻塞时运行。


一个线程由表示一个进程里的一个执行上下文所需的信息组成。这包括一个在进程里标识线程的 线程ID、一组寄存器值、一个栈、一个调用优先级和策略、一个信号掩码、一个errno变量(1.7节)、和线程指定数据(12.6节)。在一个进程内的 所有东西在进程里的线程间都可以共享,包括可执行程序的代码、程序的全局和堆内存、栈、和文件描述符。


我们将看到的线程接口是从 POSIX.1-2001而来。线程接口,也被称为“pthreads”,表示“POSIX threads”,是POSIX.1-2001的可选特性。POSIX线程的特性测试宏是_POSIX_THREADS。应用可以在#ifdef使用它或 在sysconf里使用_SC_THREADS常量来确定线程是否被支持。


正如每个进程有一个进程ID,每个线程也有一个线程ID。不像在系统唯一的进程ID,线程ID只在它所属的进程上下文里是有意义的。


回想下一个进程ID,由pid_t数据类型表示,是一个非负整数。一个线程ID由pthread_t数据类型表示。实现可以使用一个结构体来表示pthread_t数据类型,所以可移植的实现不能把它们当成是整型。因此,一个函数被用来比较两个线程ID。



  1. #include <pthreads.h>

  2. int pthread_equal(pthread_t tid1, pthread_t tid2);

  3. 相等返回非0,否则返回0.


Linux使用一个无符号长整型来表示pthread_t数据类型。Solaris用一个无符号整型表示。FreeBSD和Mac OS X用一个指向pthread结构体的指针表示。


允许pthread_t为一个结构体的一个后果是没有可移植的方法来打印它的值。有时,在程序调试时打印线程ID很重要,但是其它时候通常不需要这样做。最坏时,这导致不可移植的调试代码,所以它没有很多限制。



  1. 一个线程可以获得它自己的线程ID,通过调用pthread_self函数。

  2. #include <pthread.h>

  3. pthread_t thread_self(void);

  4. 返回调用线程的线程ID。


这 个函数可以和pthread_equal一起使用,当一个线程需要识别由它的线程ID标签的数据结构时。例如,一个主线程可以把工作分配放到一个队列里, 并使用线程ID来控制每个线程的工作。单个主线程把新的工作放到一个工作队列里。三个工作线程的线程池从队列删除工作。主线程通过在应该处理的每个工作里 放置线程ID来控制工作分配,而不是让每个线程处理任何在队列头的工作。每个工作线程然后只删除标签为它自己的线程ID的工程。

阅读(790) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~