进程与线程
进程与线程区别
Processes
- 一个基本的运算单元
- 一个地址空间
- 至少一个执行线程
Thread
- 轻量级进程
- 线程有自己的指令指针和本地变量的副本,并且独立于其他线程执行
区别
线程不同于进程
- 每个线程必须与单个进程相关联
- 虽然进程中的每个线程都有自己的局部变量副本,但一个进程中的所有线程共享访问全局变量的唯一副本
- 一个进程中的所有线程共享操作系统分配给进程的资源。
- 如果一个线程打开一个文件并获得一个描述符,其他线程可以选择访问文件的描述符。
- 类似地,如果一个线程关闭一个描述符,那么其他线程都不能继续使用它
本地变量规则
- 当多个进程或线程同时执行一段代码时,每个进程或线程都会创建与其代码相关的变量的独立副本(本地变量)
全局变量规则
- 每个进程创建一个全局变量的副本,但单个进程中的多个线程共享进程的全局变量。
实现
为了在UNIX中创建一个新进程,一个程序调用系统函数fork
- fork将正在运行的程序划分为两个相同的进程,两个进程在同一代码中的同一位置执行
- 两个进程继续运行,就像两个用户同时启动了两个应用程序副本一样。
|
fork返回值在原来与新建的进程中是不同的,在原来进程中返回的是子进程的PID ,而在(新建的)子进程中返回值是0
进程的实现并不能实现并行,只能是并发,(同时开始,CPU时间分片式的运行各自代码)。所以就会有进程间的切换开销。当每个子进程的执行任务时间较短,但是进程很多时就会造成这种开销更大。
所以通过PID让父子进程执行不同的代码。
switch( pid ) { |
select
- 允许程序询问操作系统哪些I/O设备已准备好使用,
- 告诉内核,让内核监听设备的可操作性,解放程序主动监听。
- 允许一个进程去管理并发I/O;
线程使用
创建和收获线程
- pthread_create()
- pthread_join()
|
- 参数
- 第一个参数为指向线程标识符的指针。
- 第二个参数用来设置线程属性。如果attr为NULL,则应使用默认属性。 如果attr指定的属性稍后被修改,则线程的属性不会受到影响。
- 第三个参数是线程运行函数的起始地址。
- 最后一个参数是运行函数的参数。
函数指针: 返回类型(* 函数名称)(参数)
指针函数: 返回类型 * 函数名称(参数)
线程创建属性
-
pthread_create()中的attr参数是一个结构指针,结构中的元素分别对应着新线程的运行属性,主要包括以下几项:
-
__detachstate, 表示新线程是否与进程中其他线程脱离同步,如果置位则新线程不能用pthread_join()来同步,且在退出时自行释放所占用的资源。缺省为 PTHREAD_CREATE_JOINABLE状态。这个属性也可以在线程创建并运行以后用pthread_detach()来设置,而一旦设置为 PTHREAD_CREATE_DETACH状态(不论是创建时设置还是运行时设置)则不能再恢复到 PTHREAD_CREATE_JOINABLE状态。
-
__schedpolicy,表示新线程的调度策略,主要包括 SCHED_OTHER(正常、非实时)、SCHED_RR(实时、轮转法)和 SCHED_FIFO(实时、先入先出)三种,缺省为SCHED_OTHER,后两种调度策略仅对超级用户有效。运行时可以用过 pthread_setschedparam()来改变。
-
__schedparam,一个struct sched_param结构,目前仅有一个sched_priority整型变量表示线程的运行优先级。这个参数仅当调度策略为实时(即SCHED_RR 或SCHED_FIFO)时才有效,并可以在运行时通过pthread_setschedparam()函数来改变,缺省为0。
-
__inheritsched, 有两种值可供选择:PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED,前者表示新线程使用显式指定调度策略和 调度参数(即attr中的值),而后者表示继承调用者线程的值。缺省为PTHREAD_EXPLICIT_SCHED。
-
__scope, 表示线程间竞争CPU的范围,也就是说线程优先级的有效范围。POSIX的标准中定义了两个值: PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同 进程中的线程竞争CPU。目前LinuxThreads仅实现了PTHREAD_SCOPE_SYSTEM一值。
-
pthread_attr_t结构中还有一些值,但不使用pthread_create()来设置。
-
-
为了设置这些属性,POSIX定义了一系列属性设置函数,包括
pthread_attr_init()、pthread_attr_destroy()和与各个属性相关的pthread_attr_get—/pthread_attr_set—函数。
线程属性
- pthread_attr_init()
- pthread_attr_destroy()
|
确定线程ID
- pthread_self()
|
终止线程
- pthread_exit()
- Pthread_cancel()
|
线程互斥
|
使用
/*声明互斥变量*/ |