进程的定义:进程是为了描述程序在并发执行时对系统资源的共享,所需的一个描述程序执行时动态特征的概念。进程是具有独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配、调度和保护的独立单位。 线程的定义:线程也成为轻量级进程,是进程中的一个运行实体,作为CPU的调度单位。一个进程由多个线程组成,线程与同属一个进程的其他的线程共享进程所拥有的全部资源。 同一进程内的所有线程除了共享全局变量外还共享:
进程指令;mm;代码段(代码和常量);数据段(全局变量和静态变量)扩展段(堆存储)打开的文件(即描述符);信号处理函数和信号处置;当前工作目录;用户ID和组ID。 每个线程拥有各自的:线程ID;寄存器集合,包括程序计数器和栈指针;栈(用于存放局部变量和返回地址);errno;信号掩码;优先级。 结构上的不同可以让我们更加了解进程和线程的相异之处: (1)进程是资源分配的基本单位;线程与资源分配无关,它属于某一个进程,并与进程内的其他线程共享进程的资源。 (2)当进程发生调度时,不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。 (3)线程只由先关堆栈(系统栈或用户栈)寄存器和线程控制块组成。寄存器用来存储线程内的局部变量,但不能存储其他线程的相关变量。 (4)进程切换时涉及有关资源指针的保存和地址空间的变化;线程切换时,由于处于同一进程内,所以不涉及资源信息的保存和地址空间的变化,从而减少了操作系统的时间开销fork(),子进程会拷贝父进程资源,但是不共享,彼此隔离。这里可以引申一下**写时拷贝技术**。
vfock(),子进程会拷贝父进程资源,但是内存不会拷贝,与父进程共享一个内存(物理地址)。
join join是三种同步线程的方式之一。另外两种分别是互斥锁(mutex)和条件变量(condition variable)。 调用pthread_join()将阻塞自己,一直到要等待加入的线程运行结束, 或者调用了pthread_exit,或者被取消。 可以用pthread_join()获取线程的返回值。 一个线程对应一个pthread_join()调用,对同一个线程进行多次pthread_join()调用是逻辑错误。 join or detach 线程分两种:一种可以join,另一种不可以。该属性在创建线程的时候指定。 joinable线程可在创建后,用pthread_detach()显式地分离。但分离后不可以再合并。该操作不可逆。 为了确保移植性,在创建线程时,最好显式指定其join或detach属性。似乎不是所有POSIX实现都是用joinable作默认。
创建一个线程默认的状态是joinable, 如果一个线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process,即还有一部分资源没有被回收(退出状态码),所以创建线程者应该调用pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源(类似于wait,waitpid) 。但是调用pthread_join(pthread_id)后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此,比如在Web服务器中当主线程为每个新来的链接创建一个子线程进行处理的时候,主线程并不希望因为调用pthread_join而阻塞(因为还要继续处理之后到来的链接), 这时可以在子线程中加入代码 pthread_detach(pthread_self()) ,或者父线程调用 pthread_detach(thread_id)(非阻塞,可立即返回) ,这将该子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源。
