Unix/Linux操作系统-线程管理

一、线程基本概念

  1. 线程就是进程中的执行路线,即进程内部的控制序列,或者说是进程的子任务(进程就是正在运行的程序,它是一个资源单位)
  2. 线程是轻量级的,没有自己独立的内存资源,使用的是进程的代码段,数据段,bss段,堆(注意没有栈),环境变量表、命令行参数、文件描述符、信号处理函数、工作目录、用户ID、组ID等资源
  3. 线程拥有自己独立的栈,也就是有自己独立的局部变量
  4. 一个进程中可以同时拥有多个线程,即同时被系统调度的多条执行路线,但至少有一个主线程

二、线程基本特点

  1. 线程是进程的实体,可作为系统独立的调试和分派基本单位
  2. 线程有不同的状态,系统提供了多种线程控制的原语(控制方法)
  3. 线程不拥有自己的资源(唯一拥有的就是自己的栈空间),只拥有从属于进程的全部资源,所有有资源分配都是面向进程的
  4. 一个进程中可以有多个线程同时执行,他们可以执行相同的代码,也可以执行不同的代码
  5. 同一进程内的线程都在同一地址空间下活动(0~4G),相对于多进程,多线程的系统开销小,任务切换快
  6. 多进程协同工作时需要通信,而多线程间的数据交换不需要依赖类似IPC的特殊通信机制,简单而高效
  7. 每个线程拥有自己独立的线程ID、寄存器信息、函数栈等
  8. 线程之间也存在优先级

三、POSIX线程

  1. 早期的UNIX操作系统是没有线程的,而各个计算机厂商提供自己私有的线程库,不易于移植
  2. 在1995年左右,定义了统一的线程编程接口。POSIX线程,即pthread
  3. pthread包含一个头文件pthread.h,一个共享库libpthread.so
  4. 功能:
    • 线程管理:创建/销毁、分离/联合、设置/获取属性
    • 线程同步(互斥):互斥量(互斥锁)、条件变量、信号量

四、线程函数

头文件#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:线程的入口函数
arg:给线程入口函数传递的参数

练习1:把tcp的S端的多进程改成多线程


等待线程结束

函数声明int pthread_join(pthread_t *thread, void **retval);
功能:等待线程结束获取线程入口函数的返回值,线程结束时该函数才返回
thread:获取线程ID
retval:指针变量的地址,用于获取线程入口函数的返回值
注意:线程入口函数在返回数据时,不能返回指针私有栈空间爱你的指针,如果获取到的是指向堆的指针


获取当前线程ID

函数声明int pthread_self(void);


比较线程ID

函数声明int pthread_equal(pthread_t t1, pthread_t t2);
功能:比较线程ID:如果两个线程ID是用一个线程,则返回0,否则返回-1
注意:pthread_t不一定是unsigned long 类型,有些系统中它是结构体类型,所以无法使用 == 进行比较


线程终止

函数声明void pthread_exit(void **retval);
功能:调用者线程结束(从入口函数return)
retval:会返回给pthread_join函数的第二个参数
注意:如果是进程的最后一个线程,当调用pthread_exit时进程也结束


线程分离

  • 分离态:线程可以被创造者调用pthread_join等待(回收资源)
  • 非分离态:线程不需要创造者等待,结束后自动释放资源

函数声明int pthread_detach(pthread_t thread);
功能:使调用线程与线程ID为thread线程成为分离状态


线程取消

头文件#include <pthread.h>
函数声明int pthread_cancel(pthread_t thread);
功能:向指定的线程发送取消操作
注意:对方不一定响应,响应则取消


设置手否响应取消线程操作

函数声明:int pthread_setcancelstate(int state, int *oldstate);
state

  • PTHREAD_CANCEL_ENABLE : 允许响应
  • PTHREAD_CANCEL_DISABLE:禁止相应
    oldstate:获取旧的取消状态

线程属性

 typedef union
	{
		char __size[__SIZEOF_PTHREAD_ATTR_T];
		long int __align;
	}pthread_attr_t;
	猜测:不让手动修改线程的各大项属性,而使用pthread_attr_set/get系列函数来操作。
功能:初始化线程属性

int pthread_attr_init(pthread_attr_t *attr);

功能:销毁线程属性

int pthread_attr_destroy(pthread_attr_t *attr);


功能:设置线程属性中分离标志

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
detachstate:

  • PTHREAD_CREATE_DETACHED :分离
  • PTHREAD_CREATE_JOINABLE :不分离
功能:获取线程属性中分离标志

int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);


功能:设置线程属性中线程的竞争范围

int pthread_attr_setscope(pthread_attr_t *attr, int scope);

  • PTHREAD_SCOPE_SYSTEM :系统中
  • PTHREAD_SCOPE_PROCESS:过程中
功能:获取线程属性中线程的竞争范围

int pthread_attr_getscope(pthread_attr_t *attr, int *scope);


功能:设置线程属性中线程的调度策略的来源

int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
inheritsched

  • PTHREAD_INHERIT_SCHED 继承创建者
  • PTHREAD_EXPLICIT_SCHED 单独设置
功能:获取线程属性中线程的调度策略来源

int pthread_attr_getinheritsched(pthread_attr_t *attr,int *inheritsched);


功能:设置线程属性中线程的调度策略

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

  • SCHED_FIFO 先进先出策略
  • SCHED_RR 轮转
  • SCHED_OTHER 缺省
功能:获取线程属性中线程的调度策略

int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);


功能:设置线程属性中线程的调度参数(优先级别)

int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);
param: 最高级别 0 :就绪状态

功能:获取线程属性中线程的调度参数(优先级别)

int pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param);


功能:设置线程属性中栈尾的警戒区大小,默认一页

int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);

功能:获取线程属性中栈尾的警戒区大小

int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);


功能:设置线程属性中线程的栈底地址

int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);

功能:获取线程属性中线程的栈底地址

int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr);


功能:设置线程属性中线程的栈空间字节数

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

功能:获取线程属性中线程的栈空间字节数

int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);


功能:设置线程属性中线程的栈底地址和栈空间字节数

int pthread_attr_setstack(pthread_attr_t *attr,void *stackaddr, size_t stacksize);

功能:获取线程属性中线程的栈底地址和栈空间字节数

int pthread_attr_getstack(pthread_attr_t *attr,void **stackaddr, size_t *stacksize);


功能:获取制定线程的属性

int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);


使用方法

  1. 定义线程属性结构体
  2. 初始化线程属性结构体
  3. 使用pthread_attr_set系列函数对结构体变量进行设置
  4. 在创建线程时(pthread_create函数的第二个参数)使用线程属性结构体变量创建线程

作业:实现聊天室

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值