linux高级程序_进程间通信

来源:互联网 发布:免费qq群排名优化 编辑:程序博客网 时间:2024/05/21 08:51

linux进程间通信实质就是I/O操作
通信方式:
1管道
2信号
3共享内存
4消息队列
5信号量
6基于套接字(socket)的进程通信
无名管道:
例子:
①建立一个管道
②父进程写入一些内容
③子进程读取一些内容,并且打印出来
思路:
① pipe()建立管道
②fork()生产新进程
③判断,如果是父,则写入管道内容fd(1)
④判断,如果是子,则读出管道内容fd(0)
⑤关闭文件描述符

1 #include<unistd.h>  2 #include<stdio.h>  3 #include<stdlib.h>  4 #include<string.h>  5 int main()  6 {  7     int pfd[2];  8     pid_t pid;  9     char w_cont[] = "hello"; 10     char r_cont[255]; 11     //creat pipe 12     if(pipe(pfd) < 0) 13     { 14         //failed 15         perror("creat pipe failed"); 16         return -1; 17         }else{ 18             if((pid = fork()) < 0){ 19  20                 perror("creat process failed"); 21                 }else if(pid > 0){ 22                     //parent process 23                     close(pfd[0]); 24                     write(pfd[1],w_cont,strlen(w_cont)); 25                     close(pfd[1]); 26  27                     }else{ 28                         //child process 29  30                         close(pfd[1]); 31                         read(pfd[0],r_cont,255); 32                         printf("child process read:%s\n",r_cont); 33                         } 34             } 35     return 0; 36     }

程序有点问题,输出有乱码 原因为没有结束标志
有名管道
函数原型
int mkfilo(const char *pathname,mode_t mode)
编码操作
建立有名管道文件让两个进程操作这个文件 open write read
例子
1建立一个fifo_r 用来读取有名管道
2建立一个fifo_w用来写入有名管道
3两个进程通过有名管道通信

  #include<sys/types.h>  #include<sys/stat.h>  #include<stdlib.h>  #include<string.h>  #include<stdio.h>  #include<fcntl.h>  #include<unistd.h>  #include<errno.h>  #define FIFO_PATH "myfifofile"  // read file  int main()  {    int fd;    char cont_r[255];    //create fifo file    if(mkfifo(FIFO_PATH,0666) < 0 && errno != EEXIST )    {        perror("create fifo failed");        return -1;        }else        {            printf("create fifo success\n");            //open fifo file            fd = open(FIFO_PATH,O_CREAT|O_RDONLY,0666);            if(fd>0)            {            //read content            while(1)            {                read(fd,cont_r,255);                printf("read:%s\n",cont_r);                }            }else            perror("open failed");            return 0;        }}
  #include<stdlib.h>  #include<string.h>  #include<stdio.h>  #include<fcntl.h>  #include<errno.h>  #include <unistd.h>  #define FIFO_PATH "myfifofile"                // writ file      int main()      {       int fd;       char cont_w[] = "hello my sun !";         //create fifo file      if(mkfifo(FIFO_PATH,0666) < 0 && errno != EEXIST)      {          perror("create fifo failed");          return -1;      }else      {        printf("create fifo success\n");          //open fifo file          fd = open(FIFO_PATH,O_CREAT|O_WRONLY,0666);          if(fd > 0)          {              //read content              while(1)              {                  write(fd,cont_w,strlen(cont_w));                          printf("write success\n");                          sleep(2);                  }              }else              perror("open failed");              return 0;      }      }

信号
即为软中断信号,用来通知进程发生了异步事件
进程处理信号的方式:
1忽略此信号(SIGKILL SIGSTOP 不能被忽略)
2执行用户希望的动作
3执行系统默认的动作
常用的信号
向进程本身发送信号 int raise(int SIGNO)

#inxlude<signal.h>#include<stdio.h>int main(){pid_t pid;if((pid = fork()) < 0)printf("error");}else if(pid == 0){}else{while(1){pid++;    }}return 0;}

向指定进程发送信号
int kill(pid_t pid ,int SIGNO)

#include<signal.h>#include<stdio.h>#include<sys/types.h>int main(){//kill process 3031kill(3031,SIGKILL);printf("process 3031 was killed\n");return 0;}

特殊发送信号函数
unsigned int alarm(unsigred int seconds)
默认信号是退出

#include<unistd.h>#include<stdio.h>int main(){int a;alarm(2);while(1){a++;}printf("exit\n");return 0;}

等待信号 pause()
简单的信号处理
typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);
函数指针 一个函数的首地址
指针函数 返回值是指针的函数

#include<signal.h>#include<unistd.h>#include<stdio.h>void sig_handler(int sig_no){if(sig_no == SIGINT){printf("get SIGINT\n");}else if(sig_no == SIGQUIT){printf("get SIGQUIT\n");}}int main(){printf("waiting for signal\n");//register signalsignal(SIGINT,sig_handler);signal(SIGQUIT,sig_handler);pause();return 0;}

输出结果

book@book-desktop:~/wanglei$ gcc -o sendsignal sendsignal.cbook@book-desktop:~/wanglei$ ./sendsignalwaiting for signal^Cget SIGINTbook@book-desktop:~/wanglei$ ./sendsignalwaiting for signal^\get SIGQUIT

内核代码 发送信号 注册信号 处理信号
共享内存
内存:虚拟内存4G
进程间通信查看命令ipcs
这里写图片描述

例子:建立两个进程,一个写一个读

#include<sys/ipc.h>#include<sys/shm.h>#include<sys/types.h>#include<string.h>#include<stdio.h>int main(){char contents[] = "hello sundy";void *share_memory = (void *)0;//1 create share memoryint shmid = shmget(123345,2048,IPC_CREAT|0666);if(shmid != -1){    //2map address    share_memory = shmat(shmid,NULL,0);    if(share_memory != (void *)-1)    {    //copy men    memcpy(share_memory,contents,12);    printf("save successed\n");    shmdt(share_memory);    }}return 0;}
    #include<sys/ipc.h>  2 #include<sys/shm.h>  3 #include<sys/types.h>  4 #include<string.h>  5 #include<stdio.h>  6 int main()  7 {  8     char contents[] = "hello sundy";  9     void *share_memory = (void *)0; 10     //1 create share memory 11     int shmid = shmget(233465,2048,IPC_CREAT|0666); 12     if(shmid != -1) 13     { 14             //2map address 15         share_memory = shmat(shmid,NULL,0); 16         if(share_memory != (void *)-1) 17         { 18             //copy men 19             //memcpy(share_memory,contents,12); 20             printf("get share memory value:%s\n",share_memory); 21             shmdt(share_memory); 22         } 23     } 24     return 0; 25 }

消息队列
这里写图片描述

#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<stdio.h>#include<string.h>struct msgbuf{long mtype;char mtext[255]; };int main(){ struct msgbuf mybuf;mybuf.mtype = 1;strcpy(mybuf.mtext,"hello sundy");//creat message queueint msgqid = msgget(2345,IPC_CREAT|0666);if(msgqid != -1){//2send messageif(msgsnd(msgqid,&mybuf,sizeof(mybuf.mtext),0) != -1){printf"send message success\n");}else    perror("msgsnd error");}else    perror("msgget error");    return 0;}
 #include<sys/types.h>  2 #include<sys/ipc.h>  3 #include<sys/msg.h>  4 #include<stdio.h>  5 #include<string.h>  6 struct msgbuf  7 {  8     long mtype;  9     char mtext[255]; 10 }; 11 int main() 12 { struct msgbuf mybuf; 13 //mybuf.mtype = 1; 14 //strcpy(mybuf.mtext,"hello sundy"); 15 //creat message queue 16 int msgqid = msgget(2345,IPC_CREAT|0666); 17 if(msgqid != -1) 18 { 19     //2recive message 20    //                                   IPC_NOWAIT if(msgrcv(msgqid,&mybuf,sizeof(mybuf.mtext),0,0) != -1) 21     { 22         printf("recrive message:%s\n",mybuf.mtext); //deletc queue if(msgctl(msgqid,IPC_RMID,0) != -1)     printf("deletc queue success\n"); 23     }else 24         perror("msgsnd error"); 25 }else 26     perror("msgget error"); 27         return 0; 28 }

信号量
这里写图片描述

0 0