Skip to content

Commit 341f235

Browse files
Update p1-ipcoverview.md
1 parent 3de073e commit 341f235

1 file changed

Lines changed: 50 additions & 6 deletions

File tree

lec10/p1-ipcoverview.md

Lines changed: 50 additions & 6 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
```
@@ -442,7 +464,7 @@ Child: read msg:test
442464
- shmget( key, size, flags) //创建共享段
443465
- shmat( shmid, *shmaddr, flags) //把共享段映射到进程地址空间
444466
- shmdt( *shmaddr)//取消共享段到进程地址空间的映射
445-
- shmctl() //共享段控制
467+
- shmctl(shmid, cmd, shmid_ds *buf) //共享段控制
446468

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

@@ -451,6 +473,9 @@ Child: read msg:test
451473

452474
![w:900](figs/shm-imp.jpg)
453475

476+
477+
478+
454479
---
455480
#### 创建共享内存
456481
```
@@ -492,6 +517,25 @@ void *shmat(int shmid, const void *shmaddr, int shmflg);
492517
- SHM_RDONLY:只读。
493518
- SHM_RND:(shmaddr 非空时才有效)
494519

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

496540
---
497541
#### 共享内存[示例程序](https://gitee.com/chyyuu/os-usrapp-lab/blob/main/c/ipc/shared-memory/)

0 commit comments

Comments
 (0)