当前位置: 首页 > news >正文

网站建设与营销服务黄骅做网站的电话

网站建设与营销服务,黄骅做网站的电话,如何制作微信小程序,晋江市住房和城乡建设局网站进程间通信#xff08;IPC#xff09;介绍 进程间通信#xff08;IPC#xff0c;InterProcess Communication#xff09;是指在不同的进程之间传播或交换信息。IPC 的方式包括管道#xff08;无名管道和命名管道#xff09;、消息队列、信号量、共享内存、Socket、Stre…进程间通信IPC介绍 进程间通信IPCInterProcess Communication是指在不同的进程之间传播或交换信息。IPC 的方式包括管道无名管道和命名管道、消息队列、信号量、共享内存、Socket、Streams 等。其中 Socket 和 Streams 支持不同主机上的两个进程间通信。 1. 管道 1.1 无名管道 1.1.1 特点 它是半双工的即数据只能在一个方向上流动具有固定的读端和写端。它只能用于父子进程之间的通信。管道是创建在内存中进程结束空间释放管道不复存在。对于它的读写可以使用普通的 read、write 等函数。 1.1.2 函数原型 #include unistd.h int pipe(int pipefd[2]);1.1.3 返回值 成功返回 0失败返回 -1。当一个管道建立时它会创建两个文件描述符fd[0] 为读而打开fd[1] 为写而打开。 1.1.4 无名管道代码示例 #include stdio.h #include stdlib.h #include string.h #include unistd.hint main() {int fd[2];int pid;char buf[128];if (pipe(fd) -1) {printf(create pipe fail\n);}pid fork();if (pid 0) {printf(create child fail\n);} else if (pid 0) {sleep(3);printf(this is father\n);close(fd[0]);write(fd[1], hello from father, strlen(hello from father));wait(NULL);} else {printf(this is child\n);close(fd[1]);read(fd[0], buf, 128);printf(read %s \n, buf);exit(0);}return 0; }注意管道的特性管道里没有数据时会阻塞。 1.2 命名管道 1.2.1 特点 命名管道可以在无关的进程之间交换数据与无名管道不同。命名管道有路径名与之相关联它以一种特殊设备文件形式存在于文件系统中。 1.2.2 函数原型 #include sys/types.h #include sys/stat.h int mkfifo(const char *pathname, mode_t mode);1.2.3 命名管道代码示例 read.c #include sys/types.h #include sys/stat.h #include stdio.h #include errno.h #include fcntl.h #include unistd.h #include string.hint main() {int fd;char buf[128] {0};if (mkfifo(./file, 0600) -1 errno ! EEXIST) {printf(mkfifo fail\n);perror(why);}fd open(./file, O_RDONLY);printf(read open success\n);while (1) {int n_read read(fd, buf, 128);printf(read %d byte, context %s \n, n_read, buf);}close(fd);return 0; }write.c #include sys/types.h #include sys/stat.h #include stdio.h #include errno.h #include fcntl.h #include unistd.h #include string.hint main() {int fd;char *str message from fifo;fd open(./file, O_WRONLY);printf(write open success\n);while (1) {write(fd, str, strlen(str));sleep(1);}close(fd);return 0; }2. 消息队列 消息队列是信息的链接表存放在内核中。一个消息队列由一个标识符即队列 ID来标识。 2.1 特点 消息队列是面向记录的其中的消息具有特定的格式以及特定的优先级。消息队列独立于发送与接收进程。进程终止时消息队列及内容并不会删除。消息队列可以实现信息的随机查询消息不一定要以先进先出的次序读取也可以按消息的类型读取。 2.2 函数原型 #include sys/types.h #include sys/ipc.h #include sys/msg.hint msgget(key_t key, int msgflg); int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); int msgctl(int msqid, int cmd, struct msqid_ds *buf);2.3 消息队列代码示例 send.c #include stdio.h #include sys/types.h #include sys/ipc.h #include sys/msg.h #include string.hstruct msgbuf {long mtype;char mtext[128]; };int main() {struct msgbuf sendBuf {888, this is msg from queue};struct msgbuf readBuf;key_t key ftok(., 1);printf(key%d\n, key);int msgId msgget(key, IPC_CREAT | 0777);if (msgId -1) {perror(why:);}while (1) {msgsnd(msgId, sendBuf, strlen(sendBuf.mtext), 0);sleep(1);printf(write success\n);msgrcv(msgId, readBuf, sizeof(readBuf.mtext), 988, 0);sleep(1);printf(read from queue: %s\n, readBuf.mtext);}msgctl(msgId, IPC_RMID, NULL);return 0; }read.c #include stdio.h #include sys/types.h #include sys/ipc.h #include sys/msg.h #include string.hstruct msgbuf {long mtype;char mtext[128]; };int main() {struct msgbuf readBuf;struct msgbuf sendBuf {988, this is msg from father};key_t key ftok(., 1);printf(key%d\n, key);int msgId msgget(key, IPC_CREAT | 0777);if (msgId -1) {perror(why:);}while (1) {msgrcv(msgId, readBuf, sizeof(readBuf.mtext), 888, 0);sleep(1);printf(read from queue: %s\n, readBuf.mtext);msgsnd(msgId, sendBuf, strlen(sendBuf.mtext), 0);sleep(1);printf(write success\n);}msgctl(msgId, IPC_RMID, NULL);return 0; }3. 信号 3.1 信号的处理 信号的处理有三种方法忽略、捕捉和默认动作。具体的信号默认动作可以使用 man 7 signal 来查看系统的具体定义。 3.2 信号处理函数的注册 信号处理函数的注册可以分为入门版和高级版 入门版signal 函数高级版sigaction 函数 3.3 信号处理发送函数 信号发送函数也分为入门版和高级版 入门版kill高级版sigqueue 3.4 signal 函数原型及示例 #include signal.htypedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);示例 #include signal.h #include stdio.hvoid handler(int signum) {printf(get signum %d\n, signum);switch (signum) {case SIGINT:printf(SIGINT\n);break;case SIGKILL:printf(SIGKILL\n);break;case SIGUSR1:printf(SIGUSR1\n);break;} }int main() {signal(SIGINT, handler);signal(SIGKILL, handler);signal(SIGUSR1, handler);while (1);return 0; }3.5 kill 函数原型及示例 #include sys/types.h #include signal.h int kill(pid_t pid, int sig);示例 #include stdio.h #include stdlib.h #include sys/types.h #include signal.hint main(int argc, char **argv) {int signum atoi(argv[1]);int pid atoi(argv[2]);printf(signum %d , pid %d \n, signum, pid);kill(pid, signum);printf(send signal ok\n);return 0; }4. 信号量 信号量semaphore是一个计数器用于实现进程间的互斥与同步而不是用于存储进程间通信数据。 4.1 特点 信号量用于进程间同步若要在进程间传递数据需要结合共享内存。信号量基于操作系统的 PV 操作程序对信号量的操作都是原子操作。支持信号量组。 4.2 函数原型 #include sys/types.h #include sys/ipc.h #include sys/sem.hint semget(key_t key, int nsems, int semflg); int semop(int semid, struct sembuf *sops, unsigned nsops); int semctl(int semid, int semnum, int cmd, ...);4.3 信号量代码示例 #include sys/types.h #include sys/ipc.h #include sys/sem.h #include stdio.h//联合体用于 semctl 初始化 union semun {int val;struct semid_ds *buf;unsigned short *array; };void pGetKey(int id) {struct sembuf set;set.sem_num 0;set.sem_op -1;set.sem_flg SEM_UNDO;semop(id, set, 1);printf(get key\n); }void pPutBackKey(int id) {struct sembuf set;set.sem_num 0;set.sem_op 1;set.sem_flg SEM_UNDO;semop(id, set, 1);printf(put back the key\n); }int main() {int semid;key_t key ftok(., 2);//1. 获取或创建信号量semid semget(key, 1, IPC_CREAT | 0666);union semun initsem;initsem.val 0;//2. 初始化信号量semctl(semid, 0, SETVAL, initsem);int pid fork();if (pid 0) {//4. 拿锁pGetKey(semid);printf(this is father\n);//5. 还锁pPutBackKey(semid);//6. 销毁锁semctl(semid, 0, IPC_RMID);} else if (pid 0) {printf(this is child\n);//3. 放锁pPutBackKey(semid);} else {printf(fork error\n);}return 0; }5. 共享内存 共享内存shared memory指两个或多个进程共享一个给定的存储区。 5.1 特点 共享内存是最快的一种 IPC因为进程是直接对内存进行存储而不需要任何数据的拷贝。只能单独一个进程写或读如果 A 和 B 进程同时写会造成数据的混乱需要搭配信号量来使用。 5.2 函数原型 #include sys/types.h #include sys/ipc.h #include sys/shm.hint shmget(key_t key, size_t size, int shmflg); void *shmat(int shmid, const void *shmaddr, int shmflg); int shmdt(const void *shmaddr); int shmctl(int shmid, int cmd, struct shmid_ds *buf);5.3 共享内存代码示例 shm_write.c #include stdio.h #include stdlib.h #include string.h #include sys/ipc.h #include sys/shm.hint main() {int shmid;char *shmaddr;key_t key ftok(., 1);// 创建共享内存shmid shmget(key, 1024 * 4, IPC_CREAT | 0600);if (shmid -1) {printf(create shm fail\n);exit(-1);}// 连接映射共享内存shmaddr shmat(shmid, 0, 0);printf(shmat OK\n);// 将数据拷贝到共享内存strcpy(shmaddr, hello world\n);sleep(5); // 等待 5 秒避免一下子断开连接。等待另外一个进程读完。// 断开共享内存连接shmdt(shmaddr);// 删除共享内存shmctl(shmid, IPC_RMID, 0);printf(quit\n);return 0; }shm_get.c #include stdio.h #include stdlib.h #include string.h #include sys/ipc.h #include sys/shm.hint main() {int shmid;char *shmaddr;key_t key ftok(., 1);// 打开共享内存shmid shmget(key, 1024 * 4, 0);if (shmid -1) {printf(create shm fail\n);exit(-1);}// 连接并映射共享内存shmaddr shmat(shmid, 0, 0);printf(get from shm_write message is: %s, shmaddr);// 断开共享内存连接shmdt(shmaddr);printf(quit\n);return 0; }6. 结合消息队列、共享内存、信号量的示例 6.1 代码示例 get.c #include stdio.h #include stdlib.h #include sys/shm.h #include sys/sem.h #include sys/msg.h #include string.h// 消息队列结构 struct msg_form {long mtype;char mtext; };// 联合体用于 semctl 初始化 union semun {int val;struct semid_ds *buf;unsigned short *array; };// 初始化信号量 int init_sem(int sem_id, int value) {union semun tmp;tmp.val value;if (semctl(sem_id, 0, SETVAL, tmp) -1) {perror(Init Semaphore Error);return -1;}return 0; }// P 操作 int sem_p(int sem_id) {struct sembuf sbuf;sbuf.sem_num 0;sbuf.sem_op -1;sbuf.sem_flg SEM_UNDO;if (semop(sem_id, sbuf, 1) -1) {perror(P operation Error);return -1;}return 0; }// V 操作 int sem_v(int sem_id) {struct sembuf sbuf;sbuf.sem_num 0;sbuf.sem_op 1;sbuf.sem_flg SEM_UNDO;if (semop(sem_id, sbuf, 1) -1) {perror(V operation Error);return -1;}return 0; }// 删除信号量集 int del_sem(int sem_id) {union semun tmp;if (semctl(sem_id, 0, IPC_RMID, tmp) -1) {perror(Delete Semaphore Error);return -1;}return 0; }// 创建一个信号量集 int create_sem(key_t key) {int sem_id;if ((sem_id semget(key, 1, IPC_CREAT | 0666)) -1) {perror(semget error);exit(-1);}init_sem(sem_id, 1); // 初值设为 1 资源未占用return sem_id; }int main() {key_t key;int shmid, semid, msqid;char *shm;struct shmid_ds buf1; // 用于删除共享内存struct msqid_ds buf2; // 用于删除消息队列struct msg_form msg; // 消息队列用于通知对方更新了共享内存// 获取 key 值if ((key ftok(., z)) 0) {perror(ftok error);exit(1);}// 创建共享内存if ((shmid shmget(key, 1024, IPC_CREAT | 0666)) -1) {perror(Create Shared Memory Error);exit(1);}// 连接共享内存shm (char *)shmat(shmid, 0, 0);if ((int)shm -1) {perror(Attach Shared Memory Error);exit(1);}// 创建消息队列if ((msqid msgget(key, IPC_CREAT | 0777)) -1) {perror(msgget error);exit(1);}// 创建信号量semid create_sem(key);// 读数据while (1) {msgrcv(msqid, msg, 1, 888, 0); // 读取类型为 888 的消息if (msg.mtext q) // quit - 跳出循环break;if (msg.mtext r) // read - 读共享内存{sem_p(semid);printf(%s\n, shm);sem_v(semid);}}// 断开连接shmdt(shm);// 删除共享内存、消息队列、信号量shmctl(shmid, IPC_RMID, buf1);msgctl(msqid, IPC_RMID, buf2);del_sem(semid);return 0; }send.c #include stdio.h #include stdlib.h #include sys/shm.h #include sys/sem.h #include sys/msg.h #include string.h// 消息队列结构 struct msg_form {long mtype;char mtext; };// 联合体用于 semctl 初始化 union semun {int val;struct semid_ds *buf;unsigned short *array; };// P 操作 int sem_p(int sem_id) {struct sembuf sbuf;sbuf.sem_num 0;sbuf.sem_op -1;sbuf.sem_flg SEM_UNDO;if (semop(sem_id, sbuf, 1) -1) {perror(P operation Error);return -1;}return 0; }// V 操作 int sem_v(int sem_id) {struct sembuf sbuf;sbuf.sem_num 0;sbuf.sem_op 1;sbuf.sem_flg SEM_UNDO;if (semop(sem_id, sbuf, 1) -1) {perror(V operation Error);return -1;}return 0; }int main() {key_t key;int shmid, semid, msqid;char *shm;struct msg_form msg;int flag 1; // while 循环条件// 获取 key 值if ((key ftok(., z)) 0) {perror(ftok error);exit(1);}// 获取共享内存if ((shmid shmget(key, 1024, 0)) -1) {perror(shmget error);exit(1);}// 连接共享内存shm (char *)shmat(shmid, 0, 0);if ((int)shm -1) {perror(Attach Shared Memory Error);exit(1);}// 创建消息队列if ((msqid msgget(key, 0)) -1) {perror(msgget error);exit(1);}// 获取信号量if ((semid semget(key, 0, 0)) -1) {perror(semget error);exit(1);}// 写数据printf(***************************************\n);printf(* IPC *\n);printf(* Input r to send data to server. *\n);printf(* Input q to quit. *\n);printf(***************************************\n);while (flag) {char c;printf(Please input command: );scanf(%c, c);switch (c) {case r:printf(Data to send: );sem_p(semid); // 访问资源scanf(%s, shm);sem_v(semid); // 释放资源// 清空标准输入缓冲区while ((c getchar()) ! \n c ! EOF);msg.mtype 888;msg.mtext r; // 发送消息通知服务器读数据msgsnd(msqid, msg, sizeof(msg.mtext), 0);break;case q:msg.mtype 888;msg.mtext q;msgsnd(msqid, msg, sizeof(msg.mtext), 0);flag 0;break;default:printf(Wrong input!\n);// 清空标准输入缓冲区while ((c getchar()) ! \n c ! EOF);}}// 断开连接shmdt(shm);return 0; }7. 对比总结 通过上述对比可以看出各种 IPC 方式各有优劣选择合适的方式进行进程间通信可以提高程序的效率和可靠性。
http://www.dnsts.com.cn/news/205912.html

相关文章:

  • 网站建设推进会怎么找平台推广自己的产品
  • 网站维护需要哪些知识网站开发总体功能设计
  • 够物网站空间100m够不够小视频做网站怎么赚钱
  • 网站换ip对优化有影响吗射阳做网站的公司
  • 深圳积分商城网站制作网站双机热备怎么做
  • 一个域名一个ip做多个网站网站开发套餐
  • 外贸网站定做中国十大少儿编程教育品牌
  • 高端制作网站哪家专业app数据分析软件
  • 企业网站开发制作费入那里郑州网站关键词优化公司哪家好
  • 咖啡色网站模板网站做代理服务器
  • 天津企业网站建设方案设计师招聘网站推荐
  • xml网站模板最近热点新闻事件
  • 织梦如何制作静态网站模板做图片推广的网站有哪些
  • 闲鱼钓鱼网站怎么制作前端自己写代码建网站要花多少钱
  • 怎么做好网站营销推广天河区做网站
  • 自助建站平台网站wordpress返回上一个网页
  • 做网站公司昆山access数据库做网站
  • 网站qq临时会话不需要添加好友平台优化是指什么
  • 深圳做网站服务公司西安百度提升优化
  • 网站建设上机考试题目天天炫拍免费做相册管方网站下载
  • get写作网站英文网站推广服务
  • 做网站和网站页面设计新闻头条免费下载安装
  • 网站地图制作怎么做网站后台密码是什么
  • 免费网站流量统计wordpress设置上传大小
  • 微网站模板开发wordpress 短链插件
  • 建设网站成本西安网站设计与建设
  • 网站做百度推广需要哪些条件图片街景位置识别
  • 免费建站系统有哪些哔哩哔哩网站
  • 网站开发所需要注意的问题ios网站开发教程
  • 网站建设报价单-中英文版网页界面布局