LINUX线程

一, 线程的概念

<1> 线程,又是被称为轻量级进程(Lightweight Process LWP),是操作系统或进程调度的最小单位。是在进程内部(地址空间)执行的。每一个程序都至少有一个线程,若程序只有一个线程,那么就是程序本身。
实际上,在Linux下没有真正意义上的线程,它是由进程模拟出来的
由于同一进程的多个线程共享同一地址空间,因此代码和数据都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一 个全局变量,在各线程中都可以访问到,除此之外,各线程共享以下进程资源和环境:

(1)文件描述符
(2)信号处理方式
(3)当前工作目录
(4)用户id和组id

但是以下资源就是线程独享的

(1)线程id
(2)上下文,包括各种寄存器的值、程序计数器和栈指针
(3)栈空间
(4)errno变量
(5)信号屏蔽字
(6)调度优先级

<2> 线程的优点:

1.创建一个新线程的代价要比创建一个新进程小得多(因此有时thread被称为轻型进程)
2.与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多(提高了并发程度)
3.线程占用的资源要比进程少很多

二, 进程与线程的区别

1.计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。
2.假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务
3.进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。
4.一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人。一个进程可以包括多个线程
5.车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存
6.每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。
7.还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。

区别:
进程——资源分配的最小单位,线程——程序执行的最小单位
进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)

三, 线程的创建/等待/终止
我们将要学习的线程库函数是由POSIX标准定义的,称为POSIX thread或者pthread。在Linux 上线程函数位于libpthread共享库中,因此在编译时要加上-lpthread选项
<1>. 线程的创建
这里写图片描述
<2>. 线程的等待
这里写图片描述
它的作用是:
a.保证退出时的退出顺序
b.回收新线程退出时的资源情况
c.获得新线程退出时结果是否正确的退出返回值
这里写图片描述
结果如下:
这里写图片描述
<3>.线程的终止
这里写图片描述
终止方式有3种
1.从线程函数内部return。注意:主线程退出,所有线程都会退出。
2. 一个线程可以调用pthread_cancel终止同一进程中的另一个线程。
3.使用pthread_exit函数终止线程。
<4>.线程的取消
这里写图片描述

测试代码:
这里写图片描述
结果如下:
这里写图片描述
这个时候的返回值是-1的原因是:如果thread线程被别的线程调用pthread_cancel异常终掉,value_ptr所指向的单元里存放的是常数PTHREAD_CANCELED。在Linux的pthread库中常数PTHREAD_CANCELED的值是-1。

四, 线程的分离与结合属性

线程属性标识符:pthread_attr_t 包含在 pthread.h 头文件中。

typedef struct  
{  
    int                   etachstate;      //线程的分离状态  
    int                   schedpolicy;     //线程调度策略  
    structsched_param     schedparam;      //线程的调度参数  
    int                   inheritsched;    //线程的继承性  
    int                   scope;           //线程的作用域  
    size_t                guardsize;       //线程栈末尾的警戒缓冲区大小  
    int                   stackaddr_set;   //线程的栈设置  
    void*                 stackaddr;       //线程栈的位置  
    size_t                stacksize;       //线程栈的大小  
}pthread_attr_t; 

在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。
为了避免存储器泄漏,每个可结合线程都应该要 么被显示地回收,即调用pthread_join;要么通过调用pthread_detach函数被分离。
由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞。因此,我们就可以在子线程中加入pthread_detach(pthread_self())或者父线程调用pthread_detach(thread_id)(非阻塞,可立即返回)
这样将子线程的状态设置为分离的(detached),如此一来,该线程运行结束后会自动释放所有资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值