网络编程4

线程管理
一、基本概念
1、线程是进程的执行路线,它是进程内部的控制序列,或者
说线程是进程的一部分(进程是一个资源单位,线程是执行单位
,线程是进程的一部分,负责真正的执行)
2、线程是轻量级的,没有自己独立的代码段、数据段、bss段、环
境变量、命令行参数、文件描述符、信号处理函数、当前目录信息等资源
3、线程有自己独立的栈内存、线程ID、错误码、信号屏蔽掩码
4、一个进程中可以包含多个线程(多个执行路线),但是至少要有一个线程
在活动,称为主线程
5、ps -T -p 查看pid进程中的线程情况 或者htop命令也可以查看
6、线程是进程的实体,可以当作系统独立的任务调度和分配的基本单位
7、系统有不同的状态、属性,系统提供了线程的控制接口,例如:创建、
销毁、控制
8、进程中的所有线程同在一个虚拟地址空间中,进程中的所有资源对于线程
而言都是共享的,因此当多个线程协同工作时需要解决资源竞争的问题(加锁)
9、线程的系统开销小、任务切换快、多个线程之间不需要数据交换、因此不需要
类似于XSI的通信机制,因此使用线程简单而高效
10、线程之间有优先级的差异

二、POSIX线程
1、早期的UNIX和Linux系统没有线程概念,微软的Windows系统首先使用
的线程,之后UNIX和Linux系统也逐渐加入了线程
2、早期各个厂商都有自己私有的线程库,而且接口的实现差异较大,不利于
移植,世界标准化组织于1995年,制定了统一的线程接口标志规范,遵循该标准
的线程称为POSIX线程,简称pthread
3、pthread线程包含一个头文件 <pthread.h> 和一个共享库libpthread.so
-pthread

三、线程管理
#include <pthread.h>

   int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                      void *(*start_routine) (void *), void *arg);

    功能:创建新线程
    thread:输出型参数,用来获取线程ID
    attr:用于设置线程属性,一般写NULL即可
    start_routine:线程的入口函数,相当于主线程的main函数
    arg:传递给start_routine入口函数的参数
    返回值:成功返回0,失败返回错误编码

    注意:入口函数的参数 返回值要确保它的可持续性,因此不太适合使用栈内存,
    可以考虑堆内存、全局变量

    int pthread_join(pthread_t thread, void **retval);
    功能:等待线程结束,并获取该线程结束时的入口函数的返回值,并释放线程资源
    thread:要等待的线程的ID
    retval:用于存储线程结束时返回值的地址
    返回值:成功返回0,失败返回错误编码

    pthread_t pthread_self(void);
    功能:获取当前线程的线程ID

    int pthread_equal(pthread_t t1, pthread_t t2);
    功能:比较两个线程ID是否一致
    返回值:一致返回非零值,不一致返回0
    注意:在个别操作系统下,pthread_t 是以结构实现的,大部分是以 unsigned long
    呈现的,为了可移植性,不能直接使用==比较
    pthread_t tid;//不要初始化 提高可移植性

四、线程的执行轨迹
同步方式:(可结合状态)
创建子线程后,主线程通过调用pthread_join函数等待子线程终止,
并释放线程资源
异步方式:(分离状态)
无需创建者等待(如果创建者调用pthread_join函数会立即返回),线
程结束时,由系统释放资源
原因:为了避免线程资源泄漏,每个可结合状态的线程必须显示地调用pthread_join
来回收资源,或者将其变成分离状态

int pthread_detach(pthread_t thread);
功能:让已创建的thread标识的线程与创建者线程分离

pthread_detach两种用法:
    1、主线程中调用pthread_datach(tid)
    2、新线程中调用pthread_detach(pthread_self())
    注意:无论哪种分离写法,都必须发送在pthread_join之前,否则
    join一旦进入等待,再分离也不会退出等待

五、线程的终止
1、线程执行了入口函数的最后一行代码 包括return语句
2、线程执行了pthread_exit函数
void pthread_exit(void *retval);
功能:结束当前线程
retval:等同于return 后面的val

    注意:从表面上看当主线程结束后,子线程会跟着一起结束,
    就会误以为主线程的结束影响了子进程的结束,但是实际上
    子线程之所以结束是因为主线程执行了main函数中隐藏的return语句,
    导致了整个进程结束,所以进程中所有的线程才会随之结束。
    如果主线程调用pthread_exit自杀,这样就没有线程去执行main函数
    的return语句,进程就不会提前结束,子线程就不受影响了
    总结:主线程结束不会影响子线程的执行

3、如果所在的进程结束,所有的线程都随之结束
4、向指定线程发送取消请求
    int pthread_cancel(pthread_t thread);
    功能:向指定线程发送取消请求,默认情况下会响应请求
    int pthread_setcancelstate(int state, int *oldstate);
    功能:设置本线程是否响应取消请求,并获取之前的状态
        PTHREAD_CANCEL_ENABLE   允许响应
        PTHREAD_CANCEL_DISABLE  禁止响应

    int pthread_setcanceltype(int type, int *oldtype);
    功能:设置延迟响应
    PTHREAD_CANCEL_DEFERRED     延迟响应 在接收到取消请求后不立即
    响应,而是等待合适的时间在响应
    PTHREAD_CANCEL_ASYNCHRONOUS     立即响应

    六、线程属性

 typedef struct pthread_attr_t
{
   int  detachstate;     线程的分离状态
   int  schedpolicy;     线程调度策略
   struct sched_param schedparam;      线程的调度参数
   int  inheritsched;    线程的继承性
   int  scope;           线程的作用域
   size_t  guardsize;    线程栈末尾的警戒缓冲区大小
   int stackaddr_set;    线程栈的设置
   void * stackaddr;     线程栈的位置
   size_t   stacksize;   线程栈的大小
}pthread_attr_t;
在/usr/include/i386-linux-gnu/bits/pthreadtypes.h这个文件中
找到关于pthread_attr_t的定义,但是该定义不是真的线程属性结构体的定
义,真实的定义应该如上所示,大概是因为pthread不想让用户看到它对
pthread_attr_t的实现,希望用户借助它提供的接口函数进行获取、设置属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值