Skip to content

Commit 9ec4495

Browse files
Merge remote-tracking branch 'refs/remotes/origin/master'
2 parents 4c78355 + 8a1530a commit 9ec4495

File tree

1 file changed

+71
-10
lines changed

1 file changed

+71
-10
lines changed

lec10/p1-ipcoverview.md

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,18 @@ $ cat name.fifo
274274
#### 消息队列实现机制
275275
![w:1000](figs/signal-imp.jpg)
276276

277+
278+
---
279+
#### ftok
280+
ftok 会基于文件的 inode 信息和 proj_id 生成一个唯一的键值。
281+
两个进程必须使用相同的 pathname 和 proj_id,才能生成相同的键值,从而访问同一个 IPC 资源。
282+
```
283+
key_t ftok(const char *pathname, int proj_id);
284+
```
285+
- pathname:一个已存在的文件路径(如进程A和B都能访问的文件)
286+
- proj_id:一个用户自定义的整型值(通常是一个字符的 ASCII 码,如 'A')。
287+
288+
277289
---
278290
#### 消息队列实现机制
279291

@@ -289,10 +301,10 @@ $ cat name.fifo
289301
#### 消息队列的系统调用
290302
<!-- https://zhuanlan.zhihu.com/p/268389190 Linux进程间通信——消息队列 -->
291303
- 消息队列的系统调用
292-
- msgget ( key, flags) //获取消息队列标识
293-
- msgsnd ( QID, buf, size, flags ) //发送消息
294-
- msgrcv ( QID, buf, size, type, flags ) //接收消息
295-
- msgctl() // 消息队列控制
304+
- msgget ( key, flags) //创建息队列
305+
- msgsnd ( msgid, buf, size, flags ) //发送消息
306+
- msgrcv ( msgid, buf, size, type, flags ) //接收消息
307+
- msgctl(msqid, cmd, msqid_ds *buf) // 消息队列控制
296308

297309
消息的结构
298310
```
@@ -398,7 +410,17 @@ int msgrcv(int msgid, void *msg_ptr, size_t msgsz,long int msgtype, int msgflg)
398410
- 成功:返回实际放到接收缓冲区里去的字符个数
399411
- 失败:则返回-1
400412

401-
413+
---
414+
#### 消息队列控制
415+
```
416+
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
417+
```
418+
- 消息队列的属性保存在系统维护的数据结构msqid_ds中,可以通过函数msgctl获取或设置消息队列的属性。
419+
- msgctl:对msgqid标识的消息队列执行cmd操作,3种cmd操作:
420+
- IPC_STAT:获取消息队列对应的msqid_ds数据结构(保存到buf)
421+
- IPC_SET:设置消息队列的属性,存储在buf中,包括:msg_perm.uid、 msg_perm.gid、msg_perm.mode、msg_qbytes
422+
- IPC_RMID:从内核中删除msgqid标识的消息队列
423+
- buf是指向msgid_ds结构的指针,指向消息队列模式和访问权限
402424
---
403425
#### 消息队列[示例程序](https://gitee.com/chyyuu/os-usrapp-lab/blob/main/c/ipc/message-queues/ex1.c)
404426
```
@@ -434,22 +456,28 @@ Child: read msg:test
434456
- 不足:需要同步机制协调数据访问
435457

436458
![w:550](figs/shmem.png)
437-
459+
460+
461+
---
462+
#### 共享内存实现机制
463+
464+
![w:900](figs/shm-imp.jpg)
465+
438466

439467
---
440468
#### 共享内存的系统调用
441469
<!-- https://zhuanlan.zhihu.com/p/147826545 Linux系统编程之进程间通信:共享内存 -->
442470
- shmget( key, size, flags) //创建共享段
443471
- shmat( shmid, *shmaddr, flags) //把共享段映射到进程地址空间
444472
- shmdt( *shmaddr)//取消共享段到进程地址空间的映射
445-
- shmctl() //共享段控制
473+
- shmctl(shmid, cmd, shmid_ds *buf) //共享段控制
446474

447475
注:需要信号量等同步机制协调共享内存的访问冲突
448476

449-
---
450-
#### 共享内存实现机制
451477

452-
![w:900](figs/shm-imp.jpg)
478+
479+
480+
453481

454482
---
455483
#### 创建共享内存
@@ -492,6 +520,25 @@ void *shmat(int shmid, const void *shmaddr, int shmflg);
492520
- SHM_RDONLY:只读。
493521
- SHM_RND:(shmaddr 非空时才有效)
494522

523+
---
524+
#### 删除共享内存
525+
```
526+
int shmdt(const void *shmaddr);
527+
```
528+
- shmaddr是shmat()函数返回的地址指针
529+
- 调用成功时返回0,失败时返回-1.
530+
531+
---
532+
#### 共享内存控制
533+
```
534+
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
535+
```
536+
- shm_id是shmget()函数返回的共享内存标识符。
537+
- cmd是要采取的操作,它可以取下面的三个值 :
538+
- IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
539+
- IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
540+
- IPC_RMID:删除共享内存段
541+
- buf是一个结构指针,它指向共享内存模式和访问权限的结构。
495542

496543
---
497544
#### 共享内存[示例程序](https://gitee.com/chyyuu/os-usrapp-lab/blob/main/c/ipc/shared-memory/)
@@ -624,8 +671,22 @@ Signals and Inter-Process Communication https://compas.cs.stonybrook.edu/~nhona
624671
---
625672
#### 信号实现机制
626673

674+
为什么需要通过sigreturn切换到用户态正常执行流程?
675+
676+
![bg right:70% 60%](figs/signal-2.png)
677+
678+
679+
---
680+
#### 信号实现机制
681+
682+
为什么需要通过sigreturn切换到用户态正常执行流程?
683+
684+
- 权限需求:只有内核能安全操作硬件上下文。
685+
- 安全校验:防止用户态篡改攻击。
686+
627687
![bg right:70% 60%](figs/signal-2.png)
628688

689+
629690
---
630691

631692
#### 信号应用编程

0 commit comments

Comments
 (0)