《Linux的进程和进程间通信 操作系统课件》由会员分享,可在线阅读,更多相关《Linux的进程和进程间通信 操作系统课件(23页珍藏版)》请在金锄头文库上搜索。
1、 fork 函数:#include pid_t fork();当一个进程调用了fork 以后,系统会创建一个子 进程。这个子进程和父进程不同的地方只有他的 进程ID 和父进程ID,就象符进程克隆(clone)自 己一样。区分父进程和子进程: 跟踪fork返回值 失败:-1 否则 父进程fork 返回子进程的ID fork 子进程返回0可根据这个返回值来区分父子进程父进程阻塞直到子进程完成任务调用wait 或者waitpid 系统调用 #include #include pid_t wait(int *stat_loc); pid_t waitpid(pid_t pid,int *stat_lo
2、c,int options);wait 系统调用 使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号 如果父进程没有子进程或者子进程已经结束了,wait 回立即返回 成功时(因一个子进程结束)wait 将返回子进程的ID,否则返回-1Waitpid: 等待指定的子进程直到子进程返回 pid 为正值:等待指定的进程(pid) pid为0:等待任何一个组ID 和调用者的组ID 相同的进程 pid=-1:等同于wait 调用。 Pidint execl(const char *path,const char *arg,.);int execlp(const char *file,const
3、char *arg,.);int execle(const char *path,const char *arg,.);int execv(const char *path,char *const argv);int execvp(const char *file,char *const argv):#include #include #include #include #include #include void main(void)pid_t child;int status;printf(“This will demostrate how to get child statusn“);i
4、f(child=fork()=-1) printf(“Fork Error :%sn“,strerror(errno); exit(1); else if(child=0) int i; printf(“I am the child:%ldn“,getpid(); for(i=0;i#include #include #include #include int main()int rtn; /*子进程的返回数值*/if ( fork() = 0 ) /* 子进程执行此命令 */execlp(“/bin/ls“,“ls -al “,(char *)0);/* 如果exec函数返回,表明没有正常执
5、行命令,打印错误信息*/exit( 1 );else /* 父进程, 等待子进程结束,并打印子进程的返回值 */wait ( printf( “ child process return %dn“,. rtn );主要手段: 管道(Pipe) 信号(Signal) 消息(Message) 共享内存(Shared memory) 信号量(Semaphore) 套接口(Socket)进程通信的另一个方法是使用共享内存。System V 提供了以下几个 函数以实现共享内存: #include #include #include int shmget(key_t key,int size,int sh
6、mflg); void *shmat(int shmid,const void *shmaddr,int shmflg); int shmdt(const void *shmaddr); int shmctl(int shmid,int cmd,struct shmid_ds *buf);size 是共享内存的大小shmat 是用来连接共享内存shmdt 是用来断开共享内存的#include #include #include #include #include #define PERM S_IRUSR|S_IWUSRint main(int argc,char *argv)int shmid
7、;char *p_addr,*c_addr;if(argc!=2)printf(“Usage:%sna“,argv0);exit(1);if(shmid=shmget(IPC_PRIVATE,1024,PERM)=-1)printf(“Create Share Memory Errorna“);exit(1);if(fork()p_addr=shmat(shmid,0,0);memset(p_addr,0,1024);strncpy(p_addr,argv1,1024);exit(0);elsec_addr=shmat(shmid,0,0);printf(“Client get %s“,c_a
8、ddr);exit(0);为了便于进程之间通信, 可以使用管道通信System V 提供的函数来 实现进程的通信,这就是消息队列。 #include ;#include ;#include ;int msgget(key_t key,int msgflg);int msgsnd(int msgid,struct msgbuf *msgp,int msgsz,int msgflg);int msgrcv(int msgid,struct msgbuf *msgp,int msgsz, long msgtype,int msgflg);int msgctl(Int msgid,int cmd,st
9、ruct msqid_ds *buf);struct msgbuf long msgtype; /* 消息类型*/. /* 其他数据类型*/msgget 函数返回一个消息队列的标志msgctl 函数对消息进行控制msgsnd 和msgrcv 函数进行消息通讯 msgid 是接受或者发送的消息队列标志 msgp 是接受或者发送的内容 msgsz 是消息的大小 结构msgbuf 包含的内容是至少有一个为msgtype,其他的成分 是用户定义的。 对于发送函数msgflg 指出缓冲区用完时候的操作,接收函数指出 无消息时候的处理.一般为0. 接收函数msgtype 指出接收消息时候的操作: 如果ms
10、gtype=0,接收消息队列的第一个消息 大于0 接收队列中消息类型等于这个值的第一个消息 小于0 接收消息队列中小于或者等于msgtype 绝对值的所有消息中的最 小一个消息#include #include #include #include #include #include #include #include #include #define MSG_FILE “server.c“#define BUFFER 255#define PERM S_IRUSR|S_IWUSRstruct msgtype long mtype;char bufferBUFFER+1;int main()st
11、ruct msgtype msg;key_t key;int msgid;/*key_t ftok(char * pathname,char projid)据pathname和proj来创建一个关键字,*/*此关键字在创建信号量,创建消息队列的时候都需要使用。其中pathname必须是一*/*个存在的可访问的路径或文件,proj必须不得为0。*/if(key=ftok(MSG_FILE,a)=-1) printf(“Creat Key Errorn“); exit(1);if(msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL)=-1) printf(“Creat
12、 Message Errorn“); exit(1);while(1) msgrcv(msgid, printf(“Server Receive:%sn“,msg.buffer); msg.mtype=2; msgsnd(msgid,exit(0);#include #include #include #include #include #include #include #include #define MSG_FILE “server.c“#define BUFFER 255#define PERM S_IRUSR|S_IWUSRstruct msgtype long mtype;char
13、 bufferBUFFER+1;int main(int argc,char *argv)struct msgtype msg;key_t key;int msgid;if(argc!=2) printf(“Usage:%s stringna“,argv0); exit(1);if(key=ftok(MSG_FILE,a)=-1) printf(“Creat Key Error:n“); exit(1);if(msgid=msgget(key,PERM)=-1) printf(“Creat Message Error:an“); exit(1);msg.mtype=1;strncpy(msg.buffer,argv1,BUFFER);msgsnd(msgid,memset(msgrcv(msgid,printf(“Client receive:%sn“,msg.buffer);exit(0);