Linux之进程通信
来源:互联网 发布:矩阵理论与应用 pdf 编辑:程序博客网 时间:2024/06/01 20:26
一、共享内存:
系统调用:shmget();当shmget()创建了一块新的共享内存后,返回一个可以用于引用该共享内存的shmid_ds数据结构的标识符。
原型:int shmget(key_t key,int size,int shmflg);
返回值:如果成功,返回共享内存段标识符。
如果失败,则返回-1
系统调用:shmat();将共享内存区域映射到自己进程中去。
原型:int shmat(int shmid,char *shmadddr,int shmflg);
返回值:如果成功,则返回共享内存段连接到进程中的地址。
如果失败,则返回-1。
系统调用:shmdt();当一个进程不再需要共享的内存段时,它将会把内存段从其他地址空间中脱离。
原型:int shmdt(char *shmaddr);
返回值:如果失败,则返回-1
实例代码:shmadd.c
#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <stdio.h>#include <stdlib.h>#define BUFSZ 2048int main(){ int shmid; char *shmadd; if((shmid=shmget(IPC_PRIVATE,BUFSZ,0666))<0){ perror("shmget"); exit(1);}else printf("created shared-memory:%d\n",shmid);system("ipcs -m");/*ipcs 命令往标准输出写入一些关于活动进程间通信设施的信息。*/if((shmadd=shmat(shmid,0,0))<(char *)0){ perror("shmat"); exit(1); }else printf("attached shared-memory\n");system("ipcs -m");if((shmdt(shmadd))<0){ perror("shmdt"); exit(1); }else printf("deleted shared-memory\n");system("ipcs -m");exit(0);}
二、消息队列:
消息队列就是消息的一个链表,它允许一个或多个进程向它写消息,一个或多个进程从中读消息。具有一定的FIFO的特性,但是可实现消息的随即查询。这些消息存在内核中,由“队列ID”来标识。
消息队列的实现包括创建和打开队列、添加消息、读取消息和控制消息队列这四种操作。
int msgget(key_t key,int flag):创建和打开队列,其消息数量受系统限制。
int msgsnd(int msqid,struct msgbuf *msgp,size_t msgsz,int flag):添加消息,将消息添加到消息队列尾部。
int msgrcv(int msqid,struct msgbuf *msgp,size_t msgsz,long msgtyp,int flag):读取消息,从消息队列中取走消息。
int msgctl(int msqid,int cmd,struct msqid_ds *buf):控制消息队列。
实例代码msg.c
#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#define BUFSZ 512struct message{ long msg_type; char msg_text[BUFSZ];};int main(){ int qid; key_t key; int len; struct message sndmsg,rcvmsg; if((key=ftok(".","a"))==-1) { perroe("ftok"); exit(1); } if((qid=msgget(key,IPC_CREAT|0666))==-1) { perror("msgget"); exit(1); } printf("opened queue %d\n",qid); puts("Please enter the message to queue:"); if((fgets((&sndmsg)->msg_text,BUFSZ,stdin))==NULL) { puts("no message"); exit(1); } sndmsg.msg_type=getpid(); len=strlen(sndmsg.msg_text); if((msgsnd(qid,&sndmsg,len,0))<0) { perror("message posted"); exit(1); } if((msgrcv(qid,&rcvmsg,BUFSZ,0,0)<0) { perror("msgrcv"); exit(1); } printf("message is :%s\n",(&rcvmsg)->msg_text); if((msgctl(qid,IPC_RMID,NULL))<0) { perror("msgctl"); exit(1); } exit(0); }
三、管道
创建一个简单的管道,可以使用系统调用pipe()。他接受一个参数,也就是一个包括两个整数的数组。如果系统调用成功,此数组将包括管道使用的两个文件描述符。创建一个管道之后,一般情况下进程将产生一个新的进程。
系统调用:pipe();
原型:int pipe(int fd[2]);
注意:fd[0]用于读取管道,fd[1]用于写入管道。
一个管道是半双工的。
管道实例代码:
#include <unistd.h>#include <sys/types.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>int main(){ int pipe_fd[2];/*管道描述符*/ pid_t pid; /*定义进程ID*/ char buf_r[100];/*读的字符串*/ char *p_wbuf; /*写的字符串的指针*/ int r_num; memset(buf_r,0,sizeof(buf_r));/*将buf_r字符数组中的数据全都清为0*/ if(pipe(pipe_fd)<0) { printf("pipe create error\n"); return -1; } /*父进程写,子进程读*/ if((pid=fork())==0) /*在fork()创建的子进程当中*/ { printf("\n"); close(pipe_fd[1]);/*写管道描述符关闭*/ sleep(2); /*休眠2秒*/ if((r_num=read(pipe_fd[0],buf_r,100))>0) /*在pipe_fd[0]的管道描述符中读100个字节放入到buf_r中*/ { printf("%d numbers read from the pipe is %s\n",r_num,buf_r); } close(pipe_fd[0]);/*写管道描述符关闭*/ exit(0); /*退出*/ } else if(pid>0) { close(pipe_fd[0]);/*读管道描述符关闭*/ if(write(pipe_fd[1],"Hello",5)!=-1) printf("parent write1 success!\n"); if(write(pipe_fd[1],"Pipe",5)!=-1) printf("parent write2 success!\n"); close(pipe_fd[1]; sleep(3); waitpid(pid,NULL,0); exit(0); } }
- Linux之进程通信
- linux进程通信之管道
- linux应用之----进程通信
- linux 进程通信之信号
- linux进程通信之信号
- Linux进程通信之信号
- Linux进程通信之信号
- Linux进程通信之信号量
- Linux 进程通信之管道
- linux 进程通信之 信号
- linux 进程通信之 信号量
- Linux进程通信之管道
- linux进程通信之fifo
- linux进程通信之pipe
- Linux之------进程间通信
- Linux之------进程间通信
- Linux之------进程间通信
- Linux进程通信之信号
- 使用 fetchmail
- 如何避免网站个人信息被搜索引擎搜到
- 最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用19
- Fetchmail使用简介
- 欢迎访问个人博客网站
- Linux之进程通信
- 最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用20
- 最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用21
- 一个简单的小应用——总结
- eclipse 3.6 慢 卡 原因之一
- 最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用22
- C# 结合Microsoft.Office.Interop.Excel写入Excel
- SQL SERVER 2005 中,对两集合中有多少相同元素的检测
- 最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用23