提到线程,不得不让人想起进程,所以还是先写下进程与线程的区别吧!
一、进程与线程的区别
进程是程序执行的一个实例,进程有其自己独立的地址空间。一个线程可以含有多个线程,这也是为了提高系统资源利用率,线程的引入有其必然的优势,线程有自己的堆栈。记得操作系统的书籍上有一句经典的话:进程——资源分配的最小单位,线程——程序执行的最小单位。一个通俗的比喻:进程就像一个人,而线程就好像人体内协调工作的各个组织部分,比如血液循环,人的呼吸,心脏的跳动,他们协同工作,共用人体(进程独立的资源空间)。
二、线程操作的基本函数
1、创建线程函数
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp,
const pthread_attr_t *restrict attr,
void *(*start_rtn)(void),
void *restrict arg);
成功创建返回0,返回其他值出错。
tidp:指向线程标识符的指针。
attr:设置线程属性。
start_trn:线程运行函数的起始地址。
arg:运行函数的参数。
2、线程属性函数
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);//对线程属性进行初始化。
int pthread_attr_destroy(pthread_attr_t *attr);//去除线程的初始化属性。
若成功返回0,失败返回-1。
attr:线程属性变量。
调用pthread_attr_init()函数后,attr中所包含的就是系统支持的线程所有属性的默认值。pthread_attr_destroy()去除attr中的属性。线程属性结构如下:
typedef struct
{
int detachstate; 线程的分离状态
int schedpolicy; 线程调度策略
structsched_param schedparam; 线程的调度参数
int inheritsched; 线程的继承性
int scope; 线程的作用域
size_t guardsize; 线程栈末尾的警戒缓冲区大小
int stackaddr_set;
void* stackaddr; 线程栈的位置
size_t stacksize; 线程栈的大小
}pthread_attr_t;
(1)线程的分离状态
有一个函数可以对线程的分离状态进行控制。
#include <pthread.h>
int pthread_attr_getdetachstate(const pthread_attr_t *attr,int *detachstate);//获取线程的分离状态
int pthread_attr_setdetachstate(pthread_attr_t *attr,intdetachstate);//设置线程的分离状态
若成功返回0,若失败返回-1。
attr:线程属性变量。
detachstate,intdetachstate: 线程的分离状态属性。detachstate可以设置为PTHREAD_CREATE_DETACHED(分离状态启动线程),PTHREAD_CREATE_JOINABLE(正常启动线程)。
线程的分离状态决定一个线程以什么样的方式来终止自己。在默认情况下线程是非分离状态的,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。
而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态。所以如果我们在创建线程时就知道不需要了解线程的终止状态,则可以pthread_attr_t结构中的detachstate线程属性,让线程以分离状态启动。
(2)线程的继承
#include <pthread.h>
int pthread_attr_getinheritsched(const pthread_attr_t*attr,int *inheritsched);//获取线程的继承性
int pthread_attr_setinheritsched(pthread_attr_t *attr,intinheritsched);//设置线程的继承性
若成功返回0,若失败返回-1。
attr: 线程属性变量。
inheritsched: 线程的继承性。
继承性决定调度的参数是从创建的进程中继承还是使用在schedpolicy和schedparam属性中显式设置的调度信息。线程不为inheritsched指定默认值,因此如果你关心线程的调度策略和参数,必须先设置该属性。
继承性的可能值是PTHREAD_INHERIT_SCHED(表示新线程将继承创建线程的调度策略和参数)和PTHREAD_EXPLICIT_SCHED(表示使用在schedpolicy和schedparam属性中显式设置的调度策略和参数)。
如果需要显式的设置一个线程的调度策略或参数,那么就必须在设置之前将inheritsched属性设置PTHREAD_EXPLICIT_SCHED。
(3)线程的调度策略
#include<pthread.h>
int pthread_attr_getschedpolicy(const pthread_attr_t*attr,int *policy);//获取线程的调度策略
int pthread_att