OpenHarmony之进程通讯(Ⅱ)

1. 首先对进程通讯的概念进行梳理:
- **进程通信**(IPC)就是指进程之间的信息交换。实际上,**进程的同步与互斥**本质上也是一种进程通信(通信机制中拥有信号量和PV 操作的原因在此),只不过它传输的仅仅是信号量,通过修改信号量,使得进程之间建立联系,相互协调和协同工作。
- 从操作系统层面直观的看**进程通信**:为了保证安全,每个进程的用户地址空间都是**独立**的,一般一个进程不能直接访问另一个进程的地址空间。
但内核空间是每个进程都共享的,所以进程之间想要进行**信息交换**就必须通过**内核**,如下:

![](/api/attachments/368692)
**进程为什么要进行通讯?**
Harmony内核默认支持64个进程和128个任务,由进程池和任务池统一管理.内核设计联系就得有渠道,有规矩。
- **下面分析进程间九种通讯方式**
|  九种通讯方式 |  概念 |
| ------------ | ------------ |
|1.管道pipe(fs_syscall.c)   |管道是一种最基本的**IPC机制**,作用于有血缘关系的进程之间,完成数据传递。 调用pipe系统函数即可创建一个管道。   |
| 2.信号(los_signal.c)  |  信号为系统提供了一种进程间**异步通讯**的方式,一个进程不必通过任何操作来等待信号的到达。 |
|  3.消息队列(los_queue.c) |  队列又称消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的 不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。 |
|  4.共享内存(shm.c) | 共享内存是进程间通信中**最简单的方式之一**。  |
| 5.信号量(los_sem.c)  | 信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务间同步或共享资源的互斥访问。  |
|6.互斥锁 (los_mux.c) :   | 互斥锁又称**互斥型信号量**,是一种特殊的二值性信号量,用于实现对临界资源的独占式处理。  |
|7.快锁 (los_futex.c)   |   快速用户空间互斥体,是一种用户态和内核态**混合的同步机制**。|
| 8.事件 (los_event.c)  | 事件(Event)是一种任务间通信的机制,可用于任务间的同步。  |
|9.文件消息队列 (hm_liteipc.c)  | 分布式通讯  |

**下面将列举几个通讯方式进行分析:**
- 1. 信号(los_signal.c)
信号思想来自Unix,信号可以由**内核**产生,也可以由**用户进程**产生,并由内核传送给特定的进程或线程(组),若这个进程注册/安装了自己的信号处理程序,则内核会调用这个函数去处理信号,否则则执行默认的函数或者忽略.信号分为两大类:**可靠信号与不可靠信号**,前32种信号为不可靠信号,后32种为可靠信号。如下所示:

```cpp
#define SIGHUP    1    //终端挂起或者控制进程终止
#define SIGINT    2    //键盘中断(举个例子比如:break键被按下)
#define SIGQUIT   3    //键盘的退出键被按下
#define SIGILL    4    //非法指令
#define SIGTRAP   5    //跟踪陷阱(trace trap),启动进程,跟踪代码的执行
#define SIGABRT   6    //由abort(3)发出的退出指令
#define SIGIOT    
#define SIGBUS    7    //总线错误 
#define SIGFPE    8    //浮点异常
#define SIGKILL   9
#define SIGUSR1   10    //用户自定义信号1 
```
- 2. 互斥锁 (los_mux.c)
互斥锁的特点是拿不到锁往往原任务阻塞,切换到新任务运行.CPU是会一直跑的,它比自旋锁丰富的多.如下所示:
```cpp
enum {
    LOS_MUX_PRIO_NONE = 0,  //线程的优先级和调度不会受到互斥锁影响,先来后到,普通排队.
    LOS_MUX_PRIO_INHERIT = 1, //当高优先级的等待低优先级的线程释放锁时,低优先级的线程以高优先级线程的优先级运行。
           //当线程解锁互斥量时,线程的优先级自动被将到它原来的优先级
    LOS_MUX_PRIO_PROTECT = 2 
};
enum {
    LOS_MUX_NORMAL = 0,  //非递归锁 只有[0.1]两个状态,不做任何特殊的错误检,不进行deadlock detection(死锁检测)
    LOS_MUX_RECURSIVE = 1, //递归锁 允许同一线程在互斥量解锁前对该互斥量进行多次加锁。递归互斥量维护锁的计数,在解锁次数和加锁次数不相同的情况下,不会释放锁,别的线程就无法加锁此互斥量。
    LOS_MUX_ERRORCHECK = 2, //进行错误检查,如果一个线程企图对一个已经锁住的mutex进行relock或对未加锁的unlock,将返回一个错误。
    LOS_MUX_DEFAULT = LOS_MUX_RECURSIVE 
};
typedef struct { //互斥锁的属性
    UINT8 protocol;  //协议
    UINT8 prioceiling; //优先级上限
    UINT8 type;   //类型属性
    UINT8 reserved;  //保留字段
} LosMuxAttr;

**互斥锁能解决线程(任务)间共享内存的竞争,具体应用时,初始化如下所示:**
```cpp
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
{   //...
    SCHEDULER_LOCK(intSave);        //拿到调度自旋锁
    mutex->muxCount = 0;            //锁定互斥量的次数
    mutex->owner = NULL;            //持有该锁的任务
    LOS_ListInit(&mutex->muxList);    //初始化等待该锁的任务链表
    mutex->magic = OS_MUX_MAGIC;    //固定标识,互斥锁的魔法数字
    SCHEDULER_UNLOCK(intSave);        //释放调度自旋锁
    return LOS_OK;
}
```
在mutex->muxList中,用到了双向链表.muxList上是等待这把锁的所有任务的List.

>最后,文章和注解内容会存在不少错漏之处,以上即为本篇的所有内容,因学识与能力有限,如有不足之处,请多多包涵与指教!
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值