linux高级程序_进程间通信

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 3031
kill(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 signal
signal(SIGINT,sig_handler);
signal(SIGQUIT,sig_handler);
pause();
return 0;

}

输出结果

book@book-desktop:~/wanglei$ gcc -o sendsignal sendsignal.c
book@book-desktop:~/wanglei$ ./sendsignal
waiting for signal
^Cget SIGINT
book@book-desktop:~/wanglei$ ./sendsignal
waiting 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 memory
int 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 queue
int msgqid = msgget(2345,IPC_CREAT|0666);
if(msgqid != -1)
{
//2send message
if(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 }

信号量
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值