@@ -274,6 +274,18 @@ $ cat name.fifo
274
274
#### 消息队列实现机制
275
275
![ w:1000] ( figs/signal-imp.jpg )
276
276
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
+
277
289
---
278
290
#### 消息队列实现机制
279
291
@@ -289,10 +301,10 @@ $ cat name.fifo
289
301
#### 消息队列的系统调用
290
302
<!-- https://zhuanlan.zhihu.com/p/268389190 Linux进程间通信——消息队列 -->
291
303
- 消息队列的系统调用
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 ) // 消息队列控制
296
308
297
309
消息的结构
298
310
```
@@ -398,7 +410,17 @@ int msgrcv(int msgid, void *msg_ptr, size_t msgsz,long int msgtype, int msgflg)
398
410
- 成功:返回实际放到接收缓冲区里去的字符个数
399
411
- 失败:则返回-1
400
412
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结构的指针,指向消息队列模式和访问权限
402
424
---
403
425
#### 消息队列[ 示例程序] ( https://gitee.com/chyyuu/os-usrapp-lab/blob/main/c/ipc/message-queues/ex1.c )
404
426
```
@@ -434,22 +456,28 @@ Child: read msg:test
434
456
- 不足:需要同步机制协调数据访问
435
457
436
458
![ w:550] ( figs/shmem.png )
437
-
459
+
460
+
461
+ ---
462
+ #### 共享内存实现机制
463
+
464
+ ![ w:900] ( figs/shm-imp.jpg )
465
+
438
466
439
467
---
440
468
#### 共享内存的系统调用
441
469
<!-- https://zhuanlan.zhihu.com/p/147826545 Linux系统编程之进程间通信:共享内存 -->
442
470
- shmget( key, size, flags) //创建共享段
443
471
- shmat( shmid, * shmaddr, flags) //把共享段映射到进程地址空间
444
472
- shmdt( * shmaddr)//取消共享段到进程地址空间的映射
445
- - shmctl( … ) //共享段控制
473
+ - shmctl(shmid, cmd, shmid_ds * buf ) //共享段控制
446
474
447
475
注:需要信号量等同步机制协调共享内存的访问冲突
448
476
449
- ---
450
- #### 共享内存实现机制
451
477
452
- ![ w:900] ( figs/shm-imp.jpg )
478
+
479
+
480
+
453
481
454
482
---
455
483
#### 创建共享内存
@@ -492,6 +520,25 @@ void *shmat(int shmid, const void *shmaddr, int shmflg);
492
520
- SHM_RDONLY:只读。
493
521
- SHM_RND:(shmaddr 非空时才有效)
494
522
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是一个结构指针,它指向共享内存模式和访问权限的结构。
495
542
496
543
---
497
544
#### 共享内存[ 示例程序] ( 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
624
671
---
625
672
#### 信号实现机制
626
673
674
+ 为什么需要通过sigreturn切换到用户态正常执行流程?
675
+
676
+ ![ bg right:70% 60%] ( figs/signal-2.png )
677
+
678
+
679
+ ---
680
+ #### 信号实现机制
681
+
682
+ 为什么需要通过sigreturn切换到用户态正常执行流程?
683
+
684
+ - 权限需求:只有内核能安全操作硬件上下文。
685
+ - 安全校验:防止用户态篡改攻击。
686
+
627
687
![ bg right:70% 60%] ( figs/signal-2.png )
628
688
689
+
629
690
---
630
691
631
692
#### 信号应用编程
0 commit comments