ToB企服应用市场:ToB评测及商务社交产业平台

标题: 进程间通信--学习笔记 [打印本页]

作者: 北冰洋以北    时间: 2024-1-12 12:33
标题: 进程间通信--学习笔记
# 进程间通信
--pipe、FIFO、共享内存、消息队列、信号量
pipe(无名管道)

​        只能实现有亲缘关系进程之间的通信,它是单向的,
  1. int pipe(int piped[2])  //创建管道
复制代码
fd[0] : 读文件,fd[1] :写文件。
之后可以用open()、write()函数进行对管道进行操作,
创建管道要在fork()之前以保证父子进程操作是同一个管道。
FIFO(有名管道)
  1. int mkfifo(const char* pathname,mode_t mode)         //创建有名管道函数
复制代码
  1. mkfifo [option] [name]                                                          //创建有名管道命令
复制代码
  1. int access (const char* pathname,int mode)                //可用来检查管道的权限
复制代码
mode :
​        F_OK : 检查文件是否存在
​        R_OK: 检查读权限
​        W_OK: 检查写权限
​        X_OK : 检查执行权限
成功时返回 0,失败时返回 -1
管道与普通文件的区别之一,管道文件使用read()时,文件为空时进程会阻塞
信号通信


信号的发送 : kill(),raise()
  1. int kill(pid_t pid,int sig);              
复制代码
  1. int raise(int sig);
复制代码
raise()函数等价于kill(getpid(),sig);
  1. atoi() //将字符串转化为整形
复制代码
alarm()函数是一种系统调用,用于设置一个闹钟。当指定的时间过去之后,会发送一个信号给当前进程。
alarm()函数的原型是:
  1. int alarm(int seconds);
复制代码
alarm()`函数接受一个整数参数,表示闹钟应该在多少秒后响起。如果参数为0,那么闹钟将立即响起。如果函数成功执行,将返回0。如果函数执行失败,将返回-1。
当闹钟响起时,当前进程会收到一个SIGALRM信号。默认情况下,该信号将终止进程。但是,您可以使用信号处理函数来捕获SIGALRM信号并执行自定义操作。
信号的处理:
三种方式: 1)系统默认 2) 忽略 3) 捕获
  1. sighandler_t signal(int signum,sighandler_t handler);
复制代码
参数1:要进行处理的信号,shell中可通过kill -l 命令查看,
参数2:处理的方式
共享内存


在C语言中,共享内存是一种让不同进程可以访问同一块物理内存的技术。通过共享内存,不同进程可以相互通信并共享数据。
在Unix/Linux系统中,我们可以使用系统调用shmget、shmat、shmdt和shmctl来创建、映射、解除映射和删除共享内存段。
  1. int shmget(ket_t key,size_t size,int shmflg); //创建共享内存
复制代码
参数:
key_t key : IPC_PRIVATE或者是ftok()函数的返回值。(用ftok()函数后面要加上IPC_CREAT)
size_t size : 共享内存的大小
int shmflg : 权限
返回值:
成功返回内存的标识符,失败返回-1
  1. key_t ftok(const char *pathname, int id);
复制代码
这个函数根据文件名(pathname)和可选的标识符(id)来生成一个唯一的键值(key_t类型)。这个键值可以用来在后续的调用中识别同一共享内存段。
id参数通常是一个常数,用来区分不同的进程和不同的文件。如果id参数为0,那么ftok()函数会忽略它,只使用文件名作为唯一的键值。
如果函数成功执行,它将返回一个唯一的键值。如果失败,它将返回-1。
注意,ftok()函数并不是线程安全的,因为它返回的是静态内存。在多线程环境中,如果多个线程同时调用ftok()函数,可能会导致冲突。
  1. void *shmat(int shmid ,const void * shmaddr,int shmflg);
复制代码
参数:
int shmid : 共享内存的标识符
void *shmaddr: 映射到的地址,一般写NULL
int shmflg : 通常为0 表示内存可读可写 ,或者SHM_RDONLY表示只读
返回值:
成功返回共享内存映射到进程中的地址,失败返回-1.
  1. int shmdt(const void *shmaddr)
复制代码
成功返回0,失败返回-1.
只是删除进程中的地址映射,不会删除内核里面的共享内存对象,可以用shmctl()函数删除内核里的对象。
  1. int shmctl(int shmid,int cmd,struct shmid_ds *buf);
复制代码
参数:
int shmid : 要操作的共享内存的标识符
int cmd : IPC_STAT(获取对象属性)
​                                IPC_SET(设置对象属性)
​                                IPC_RMID(删除对象)
shmid_ds *buf : 指定IPC_STAT时用来保存或设置的属性.
消息队列


在C语言中,消息队列是一种进程间通信(IPC)的机制,它允许进程之间发送和接收消息。消息队列是操作系统内核维护的一种数据结构,它可以在不同的进程之间传递数据。
在C语言中,使用消息队列进行通信需要使用系统调用 msgget()、msgsnd()、msgrcv() 和 msgctl()。
  1. int msgget(key_t key,int msgflg);
复制代码
参数:
key_t key : 消息队列相关的key值
int msgflg: 访问权限
队列时链式的,所以不用像共享内存一样指定队列的大小
  1. int msgctl(int msgid,int cmd,strcut msgid_ds *buf);
复制代码
参数:
int msgid : 消息队列的ID
int cmd : 同共享内存
buf : 消息队列的缓冲区
返回值:
成功返回0,失败返回-1.
msgsnd()函数是在Unix/Linux环境中使用的,它属于POSIX消息队列API。这个函数用于发送消息到已经创建的队列中。
  1. int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);
复制代码
参数:
int msqid : 消息队列ID
void *msgp : 指向消息类型的指针
size_t msgsz : 发送消息的字节数
int msgflg : 如果为0 阻塞发送,IPC_NOWAIT: 非阻塞发送
返回值:
成功返回0 失败返回 -1
  1. size_t msgrcv(int msqid,void * msgp,size_t msgsz,long msgtyp,int msgflg);
复制代码
参数:
这个函数的返回值是接收的消息的长度(以字节为单位),如果成功;如果发生错误,则返回-1并设置errno。可能的错误包括但不限于EBADF(无效的队列描述符)、EINVAL(无效的标志)、EMSGSIZE(缓冲区太小)和ETIMEDOUT(在无消息可用时超时)
信号量

用来保护共享资源
int semget(key_t key, int nsems, int semflg);
参数:
返回值:
semctl()函数是用于控制信号量的函数之一。它是Unix/Linux操作系统中用于进程间通信(IPC)的一种机制。
  1. int semctl(int semid, int semnum, int cmd, union semun arg);
复制代码
参数说明:
  1. union semun {  
  2.     int val;            /* 用于SETVAL和GETVAL操作,可能是信号量的当前值。 */  
  3.     struct semid_ds *buf;  /*用于SETALL和GETALL操作,这个指针指向一个semid_ds结构体,*/
  4.     unsigned short *array;   /* 同样用于SETALL和GETALL操作,这个指针指向一个unsigned short类型的数组,可能是多个信号量的列表。 */  
  5.     void *ptr;            /* 用于GETOPT操作,可能是一个任意的指针,用于传递额外的参数 */  
  6. };
复制代码
返回值:
semop()函数是Unix/Linux操作系统中用于对信号量进行操作的函数之一。它是进程间通信(IPC)的一种机制,用于实现进程间的同步和互斥。
  1. int semop(int semid, struct sembuf *sops, size_t nops);
复制代码
参数说明:
sembuf结构体定义如下:
  1. struct sembuf {  
  2.     unsigned short sops;  // 操作类型(如SEM_ waits 或 SEM_posts)  
  3.     unsigned short _pad;   // 填充,使用时必须是0  
  4.     int sem_num;           // 信号量编号(在semid中)  
  5.     int sem_op;             // 操作值(-1为减,1为加)  
  6.     int sem_flg;            // 标志位(如IPC_NOWAIT为非阻塞,0表示阻塞)  
  7. };
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4