0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux进程间的五种通信方式介绍 3

jf_78858299 来源:阿Q正砖 作者:阿Q正砖 2023-02-15 10:19 次阅读

3、For Example

下面写了一个简单的使用消息队列进行IPC的例子,服务端程序一直在等待特定类型的消息,当收到该类型的消息以后,发送另一种特定类型的消息作为反馈,客户端读取该反馈并打印出来。

msg_server.c

#include#include#include#include
// 用于创建一个唯一的key#define MSG_FILE "/etc/passwd"
// 消息结构struct msg_form { long mtype; char mtext[256];};
int main(){ int msqid; key_t key; struct msg_form msg; // 获取key值 if((key = ftok(MSG_FILE,'z')) < 0) { perror("ftok error"); exit(1); }
// 打印key值 printf("Message Queue - Server key is: %d.\\n", key);
// 创建消息队列 if ((msqid = msgget(key, IPC_CREAT|0777)) == -1) { perror("msgget error"); exit(1); } // 打印消息队列ID及进程ID printf("My msqid is: %d.\\n", msqid); printf("My pid is: %d.\\n", getpid());
// 循环读取消息 for(;;) { msgrcv(msqid, &msg, 256, 888, 0);// 返回类型为888的第一个消息 printf("Server: receive msg.mtext is: %s.\\n", msg.mtext); printf("Server: receive msg.mtype is: %d.\\n", msg.mtype);
msg.mtype = 999; // 客户端接收的消息类型 sprintf(msg.mtext, "hello, I'm server %d", getpid()); msgsnd(msqid, &msg, sizeof(msg.mtext), 0); } return 0; }

msg_client.c

#include#include#include#include// 用于创建一个唯一的key#define MSG_FILE "/etc/passwd"
// 消息结构struct msg_form { long mtype; char mtext[256];};
int main(){ int msqid; key_t key; struct msg_form msg;
// 获取key值 if ((key = ftok(MSG_FILE, 'z')) < 0) { perror("ftok error"); exit(1); }
// 打印key值 printf("Message Queue - Client key is: %d.\\n", key);
// 打开消息队列 if ((msqid = msgget(key, IPC_CREAT|0777)) == -1) { perror("msgget error"); exit(1); }
// 打印消息队列ID及进程ID printf("My msqid is: %d.\\n", msqid); printf("My pid is: %d.\\n", getpid());
// 添加消息,类型为888 msg.mtype = 888; sprintf(msg.mtext, "hello, I'm client %d", getpid()); msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
// 读取类型为777的消息 msgrcv(msqid, &msg, 256, 999, 0); printf("Client: receive msg.mtext is: %s.\\n", msg.mtext); printf("Client: receive msg.mtype is: %d.\\n", msg.mtype); return 0;}

四、信号

信号量(semaphore)与已经介绍过的 IPC 结构不同,它是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。

1、特点

  1. 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。
  2. 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。
  3. 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。
  4. 支持信号量组。

2、原型

最简单的信号量是只能取 0 和 1 的变量,这也是信号量最常见的一种形式,叫做二值信号量(Binary Semaphore)。而可以取多个正整数的信号量被称为通用信号量。

Linux 下的信号量函数都是在通用的信号量数组上进行操作,而不是在一个单一的二值信号量上进行操作。

#include// 创建或获取一个信号量组:若成功返回信号量集ID,失败返回-1intsemget(key_t key, int num_sems, int sem_flags);// 对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1intsemop(int semid, struct sembuf semoparray[], size_t numops);  // 控制信号量的相关信息intsemctl(int semid, int sem_num, int cmd, ...);

当semget创建新的信号量集合时,必须指定集合中信号量的个数(即num_sems),通常为1;如果是引用一个现有的集合,则将num_sems指定为 0 。

在semop函数中,sembuf结构的定义如下:

struct sembuf {    short sem_num; // 信号量组中对应的序号,0~sem_nums-1    short sem_op;  // 信号量值在一次操作中的改变量    short sem_flg; // IPC_NOWAIT, SEM_UNDO}

其中 sem_op 是一次操作中的信号量的改变量:

  • 若sem_op > 0,表示进程释放相应的资源数,将 sem_op 的值加到信号量的值上。如果有进程正在休眠等待此信号量,则换行它们。
  • 若sem_op < 0,请求 sem_op 的绝对值的资源。
    • sem_flg 指定IPC_NOWAIT,则semop函数出错返回EAGAIN
    • sem_flg 没有指定IPC_NOWAIT,则将该信号量的semncnt值加1,然后进程挂起直到下述情况发生:
    • 当相应的资源数可以满足请求,此信号量的semncnt值减1,该信号量的值减去sem_op的绝对值。成功返回;
    • 此信号量被删除,函数smeop出错返回EIDRM;
    • 进程捕捉到信号,并从信号处理函数返回,此情况下将此信号量的semncnt值减1,函数semop出错返回EINTR
    • 如果相应的资源数可以满足请求,则将该信号量的值减去sem_op的绝对值,函数成功返回。
    • 当相应的资源数不能满足请求时,这个操作与sem_flg有关。
  • 若sem_op == 0,进程阻塞直到信号量的相应值为0:
    • sem_flg指定IPC_NOWAIT,则出错返回EAGAIN。
    • sem_flg没有指定IPC_NOWAIT,则将该信号量的semncnt值加1,然后进程挂起直到下述情况发生:
    • 信号量值为0,将信号量的semzcnt的值减1,函数semop成功返回;
    • 此信号量被删除,函数smeop出错返回EIDRM;
    • 进程捕捉到信号,并从信号处理函数返回,在此情况将此信号量的semncnt值减1,函数semop出错返回EINTR
    • 当信号量已经为0,函数立即返回。
    • 如果信号量的值不为0,则依据sem_flg决定函数动作:

在semctl函数中的命令有多种,这里就说两个常用的:

  • SETVAL:用于初始化信号量为一个已知的值。所需要的值作为联合semun的val成员来传递。在信号量第一次使用之前需要设置信号量。
  • IPC_RMID:删除一个信号量集合。如果不删除信号量,它将继续在系统中存在,即使程序已经退出,它可能在你下次运行此程序时引发问题,而且信号量是一种有限的资源。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10990

    浏览量

    206738
  • IPC
    IPC
    +关注

    关注

    3

    文章

    306

    浏览量

    51349
  • 进程间通信
    +关注

    关注

    0

    文章

    16

    浏览量

    2418
收藏 人收藏

    评论

    相关推荐

    linux操作系统下的进程通信设计

    语义的实现等等。linux进程通信的几种主要手段简介:1.管道管道是进程
    发表于 04-16 09:17

    Linux进程通信方式-管道

    Linux进程通信方式-管道分享到: 本文关键字: linux 管道
    发表于 08-29 15:29

    Linux进程通信

    华清远见嵌入式linux学习资料《Linux进程通信》,通过前面的学习,读者已经知道了进程
    发表于 09-04 10:07

    Linux学习杂谈】之进程通信

    通信方式,而Linux后面的版本当中就融合了这两个帮派的所有进程通信
    发表于 10-15 14:45

    Linux进程通信——使用共享内存

    Linux进程通信——使用共享内存 图文详情见附件
    发表于 11-21 10:53

    Linux现有的所有进程IPC方式

    在开始回答前,先简单概括性地说说Linux现有的所有进程IPC方式:1. **管道:**在创建时分配一个page大小的内存,缓存区大小比较有限;2. 消息队列:信息复制两次,额外的C
    发表于 08-20 06:17

    常用的进程通信主要有哪几种方式

    ;常用的进程通信主要有以下几种方式:1.消息队列;2. socket(本地socket和INETsocket)3.管道(有名管道和无名管道
    发表于 11-08 07:38

    进程通信方式有哪些?

    进程通信方式有哪些?
    发表于 12-24 06:46

    哪些方式可以实现Linux系统下的进程通信

    哪些方式可以实现Linux系统下的进程通信进程与线程有哪些不同之处呢?
    发表于 12-24 06:38

    Linux进程通信方式——管道

    管道是Linux进程通信的一种方式,它把一个程序的输出直接连接到另一个程序的输入。Linux的管道主要包括两种:无名管道和有名管道。
    发表于 06-01 09:13 1163次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b>间<b class='flag-5'>通信</b><b class='flag-5'>方式</b>——管道

    Linux进程间的五种通信方式介绍 1

    进程通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享内存
    的头像 发表于 02-15 10:18 1122次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b>间的五种<b class='flag-5'>通信</b><b class='flag-5'>方式</b><b class='flag-5'>介绍</b> 1

    Linux进程间的五种通信方式介绍 2

    进程通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享内存
    的头像 发表于 02-15 10:19 342次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b>间的五种<b class='flag-5'>通信</b><b class='flag-5'>方式</b><b class='flag-5'>介绍</b> 2

    Linux进程间的五种通信方式介绍 4

    进程通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享内存
    的头像 发表于 02-15 10:19 412次阅读

    Linux进程间的五种通信方式介绍 6

    进程通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享内存
    的头像 发表于 02-15 10:19 304次阅读

    Linux进程间的五种通信方式介绍 5

    进程通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享内存
    的头像 发表于 02-15 10:20 418次阅读