Linux——线程间通信(同步)总结

进程进程组成:1.进程控制块PCB2.程序段3.数据段进程控制块PCB 是内核中存放的一块PCB区域,记录型数据结构 ,PCB 记录了操作系统所需要的参数,用来描述进程目前情况和进程运行的全部信息,包括1.进程描述信息:进程标识符,识别进程用户标识,用于资源共享和保护家族关系,进程关于有父进程和子进程的信息2.处理机状态信息:包含通用寄存器、指令寄存器、程序状态字(PSW)、用...
摘要由CSDN通过智能技术生成

进程

进程组成:

1.进程控制块PCB
2.程序段
3.数据段
进程控制块PCB 是内核中存放的一块PCB区域,记录型数据结构 ,PCB 记录了操作系统所需要的参数,用来描述进程目前情况和进程运行的全部信息,包括

1.进程描述信息:
进程标识符,识别进程
用户标识,用于资源共享和保护
家族关系,进程关于有父进程和子进程的信息
2.处理机状态信息:包含通用寄存器、指令寄存器、程序状态字(PSW)、用户栈指针等
进程状态 ,用作进程调度的依据
进程的优先级,处理机运行进程的依据
进程调度需要的数据: 比如已经等待CPU的总和、进程已经执行的时间总和
事件: 进程被阻塞的原因
3.进程控制信息
程序和数据的地址
进程和同步通信机制
进程的状态: 就绪、执行、阻塞
在这里插入图片描述
上面是进程的各种状态切换

当第一初始化进程的时候,进程进入就绪状态,等待OS 分配处理机处理进程,当进程获取处理机处理,进程执行阶段,执行的时候,一般会用来处理各种事物,比如 请求 IO 处理等,但是一旦有大量IO 处理,容易进入阻塞状态,此时就是我们经常看见电脑卡死的状态,但是处理完后,进程会进入就绪状态
其实还有一种状态,finish 结束状态,但是只要进程死了就直接退出了

线程

从上面很容易看出来,创建一个进程,因为直接和linux 内核进行处理数据,需要提供大量的参数,来保障进程的安全,高效,稳定,消耗很多系统资源,但是线程就不一样,可以原理是一样的,作为轻量级,消耗系统资源很少,而且作为开发者来说,线程用起来更爽,更方便,线程只能跑在进程中,所以,和系统内核交互的数据都交给进程了,线程简单方便易用,据说进程消耗资源是线程的30倍……
线程和处理流程和 进程差不错 ,也是 就绪、执行、阻塞、结束四个状态

多线程编程的API
创建线程
int pthread_create(pthread_t *thread,pthread_attr_t *attr,void * (*func)(void * ),void *arg);
/*
只能看调用示例了:
pthread(&thrd1,NULL,(void*)task1,(void*)&g1);
phtread thrd1 表示创建线程的标识
pthread_attr_t *attr 表示线程属性NULL 默认
void task1 线程需要执行的代码
int g1 表示task1的参数
*/

函数的作用:创建一个线程

函数的原型:int pthread_create(pthread_t *thread,pthread_attr_t *attr, (void *)(*start_routine(void *),(void *)arg);

函数的参数:thread:线程的标识符

            attr:线程的属性,一般设为NULL

            start_routine:线程的执行函数

            arg:传入到线程执行函数的参数

返回 值:成功:0,出错:-1

头文 件:#include <pthread.h>

结束线程
pthread_exit(void *retval);
//retval 用来存放自杀线程退出状态
等待线程结束
// 多个线程启动后,由系统负责调度,但我们并不知道哪个会先开始和结束,只能等待
int pthread_join(pthread_t th,void **thread_return);
/*
th 等待线程的标识
thread_return 返回的状态
*/
函数的参数:th:线程的标识符

            thread_return:不为NULL时,存储线程结束时返回值

返回 值:成功:0  出错:<0

线程的属性之一:detach mode 默认是非分离状态,也就是需要主线程去回收资源的,用的是join。
分离线程怎么创建
1: 从线程的属性上去设置分离或者非分离(默认)
属性:
pthread_attr_t attr
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&tid , 属性,线程函数入口,线程函数参数)

2: 从线程函数中,必须放在第一句 pthread_detach()
3: 一定要保证在线程调用 pthread_join(tid,NULL)之前,
就已经调用过pthread_detach(tid)或者是子线程中的pthread_detach(pthread_self())),这样才能生效

主线程不想或者不能阻塞在对该子线程的回收上时候, 希望子线程能够独立行事

线程通信

互斥锁:mutex

pthread_mutex_init(pthread_mutex_t * , NULL)
restrict 表示只能通过该指针来修改该指针指向的内容

pthread_mutex_lock (pthread_mutex_t *)上锁 堵塞等待可上锁
pthread_mutex_trylock 如果已经上锁就直接返回。和锁的属性有关系, PTHREAD_MUTEX_RECURSIVE是会增加锁的个数

pthread_mutex_unlock (pthread_mutex_t *)解锁
pthread_mutex_destroy (pthread_mutex_t *) 锁就变成不可用

信号量:semaphore

基本操作: init sem_init (sem_t * , 0 , 1)
pshared == 1 表示在进程间使用该信号量,需要用到共享内存中的地址

P 操作 sem_wait() 申请资源,申请到资源就信号量-1; 如果信号量为0,则会阻塞到信号量非零才返回;
sem_trywait 申请资源,申请到资源就信号量-1;如果信号量为0直接返回
sem_timedwait 申请资源,申请到资源就信号量-1;如果信号量为0就等一段时间,还等不到就直接返回

V 操作 sem_post() 释放资源,信号量+1,而且唤醒睡眠中的等待该资源的线程或者进程

创建信号量
#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int value);
/*
功能: 初始化 信号量
返回值: 成功返回0 错误返回-1
sem: 指向信号量结构的指针
pshared 不为0 信号量在进程间共享,不然只能在本进程中的所有线程中共享
value 给出信号量的初始值
*/

信号量 P操作 -1
int sem_wait(sem_t *sem);
信号量 V操作 +1
int sem_post(sem_t *sem);
信号量删除
int sem_destroy(sem_t *sem);

条件变量 (类似于信号)

pthread_cond_init
pthread_cond_wait()
偷解锁,在解锁状态下等待,得到条件变量后再次上锁
pthread_cond_timedwait()
pthread_cond_signal()发送一次给等待该条件变量的一个进程
pthread_cond_broadcast() 发送给所有等待该条件变量的进程
pthread_cond_destroy()

读写锁

pthread_rwlock_init 函数
pthread_rwlock_destroy 函数
pthread_rwlock_rdlock 函数
pthread_rwlock_wrlock 函数
pthread_rwlock_tryrdlock 函数
pthread_rwlock_trywrlock 函数
pthread_rwlock_unlock

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值