----虽然这种模型很多年来使用得很好,但是fork时有一些问题: 【扩展信息:陪Yangyh买笔记本】
----1. fork是昂贵的。内存映像要从父进程拷贝到子进程,所有描述字要在子进程中复制等等。目前有的unix实现使用一种 叫做写时拷贝(copy-on-write)的技术,可避免父进程数据空间向子进程的拷贝。尽管有这种优化技术,fork仍然是昂贵的。 ----2. fork子进程后,需要用进程间通信(ipc)在父子进程之间传递信息。fork之前的信息容易传递,因为子进程从一开始就 有父进程数据空间及所有描述字的拷贝。但是从子进程返回信息给父进程需要做更多的工作。 ----线程有助于解决这两个问题。线程有时被称为轻权进程(lightweight process),因为线程比进程“轻权”, 一般来说,创建一个线程要比创建一个进程快10~100倍。 ----一个进程中的所有线程共享相同的全局内存,这使得线程很容易共享信息,但是这种简易性也带来了同步问题。 ----一个进程中的所有线程不仅共享全局变量,而且共享:进程指令、大多数数据、打开的文件(如描述字)、信号处理程序与 信号处置、当前工作目录、用户id与组id。 ----但是每个线程有自己的线程id、寄存器集合(包括程序计数器与栈指针)、栈(用于存放局部变量与返回地址)、error、信 号掩码、优先级。 ----在linux中线程编程符合posix.1标准,称为pthreads。所有的pthread函数都以pthread_开头。 ----以下先讲述5个基本线程函数,在调用它们前均要包括pthread.h头文件。然后再给出用它们编写的一个tcp客户/服务器程序例子。 ----第一个函数: ----int pthread_create (pthread_t *tid,const pthread_attr_t *attr,void *(*func)(void *),void *arg); ----一个进程中的每个线程都由一个线程id(thread id)标识,其数据类型是pthread_t(常常是unsigned int)。如果新的线程 创建成功,其id将通过tid指针返回。 ----每个线程都有很多属性:优先级、起始栈大小、是否应该是一个守护线程等等,当创建线程时,我们可通过初始化一个pthread_attr_t 变量说明这些属性以覆盖缺省值。我们通常使用缺省值,在这种情况下,我们将attr参数说明为空指针。 ----最后,当创建一个线程时,我们要说明一个它将执行的函数。线程以调用该函数开始,然后或者显式地终止(调用pthread_exit) ... 下一页