ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU

[应用相关] 进程间通讯 小总结

[复制链接]
295|36
 楼主 | 2019-3-25 13:20 | 显示全部楼层
linux进程间的通讯方式
01.管道(pipe)和有名管道(FIFO)
02.信号(signal)
03.消息队列
04.共享内存
05.信号量
06.套接字(socket)
 楼主 | 2019-3-25 13:20 | 显示全部楼层
管道通讯
管道是单向的、先进先出的,它把一个进程的输出和一个进程的输入连接在一起。一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据。
 楼主 | 2019-3-25 13:21 | 显示全部楼层
管道创建
   管道包括无名管道和命名管道两种,前者用于父进程和子进程的通讯,后者可用于运行与同一体系的两个进程间的通讯。
   无名管道由pipe() 函数创建,  int pipe(int filedis[2]); 当一个管道建立时,它会创建两个文件描述符:filedis[0]用于读管道,filedis[1]用于写管道。
 楼主 | 2019-3-25 13:21 | 显示全部楼层
管道关闭
   关闭管道只需将两个文件描述符关闭,可以使用普通的close函数逐个关闭。
 楼主 | 2019-3-25 13:22 | 显示全部楼层
无名管道通讯实例
  1. #include<unistd.h>
  2. #include<errno.h>
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include<sys/types.h>
  6. int main()
  7. {
  8.   int pipe_fd[2];
  9.   pid_t  pid;
  10.   char buf_r[100];
  11.   char* p_wbuf;
  12.   int r_num;
  13.   memset(buf_r,0,sizeof(buf_r));
  14.   if(pipe(pipe_fd)<0)
  15.   {
  16.     printf("pipe creat fail\n");
  17.     return -1;
  18.   }
  19.   if((pid=fork())==0)
  20.   {
  21.      close(pipe_fd[1]);
  22.      sleep(2);
  23.      if((r_num=read(pipe_fd[0],buf_r,100))>0)
  24.      {
  25.          printf("%d numbers read from the pipe is %s\n",r_num,buf_r);
  26.      }
  27.     close(pipe_fd[0]);
  28.     exit(0);
  29.   }
  30.   else if(pid>0)
  31.   {
  32.     close(pipe_fd[0]);
  33.     if(write(pipe_fd[1],"hello",5)!=-1)
  34.          printf("parent write1 hello!\n");
  35.     if(write(pipe_fd[1],"pipe",5)!=-1)
  36.          printf("parent write2 pipe!\n");
  37.     close(pipe_fd[1]);
  38.     sleep(3);
  39.     waitpid(pid,NULL,0);
  40.     exit(0);      
  41.    }
  42. }
复制代码


 楼主 | 2019-3-25 13:26 | 显示全部楼层
输出结果如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主 | 2019-3-25 13:26 | 显示全部楼层
命名管道创建
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char* pathname, mode_t mode)
pathname: FIFO文件名   mode:属性
一旦创建了一个FIFO,就可以用open打开它,一般的文件访问函数(close、 read、 write等)都可用于FIFO。
当打开FIFO时,非阻塞标志(O_NONBLOCK)将对以后的读写产生如下影响:
1.没有使用O_NONBLOCK:访问要求无法满足时进程将阻塞。如试图读取空的FIFO,将导致进程阻塞。
使用O_NONBLOCK:访问要求无法满足时进程不阻塞,立刻出错返回。
 楼主 | 2019-3-25 13:27 | 显示全部楼层
FIFO实例: fifo_write.c
  1. fifo_read.c
  2. #include<sys/types.h>
  3. #include<sys/stat.h>
  4. #include<errno.h>
  5. #include<fcntl.h>
  6. #include<stdio.h>
  7. #include<stdlib.h>
  8. #include<string.h>
  9. #define FIFO  "/home/lm/myfifo"
  10. void main()
  11. {
  12.      char  buf_r[100];
  13.      int fd;
  14.      int nread;
  15.      
  16.      if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
  17.          printf("cannot creat fifoserver\n");
  18.      printf("prepareing for reading bytes....\n");
  19.      memset(buf_r,0,sizeof(buf_r));
  20.      
  21.      fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
  22.      if(fd==-1)
  23.      {
  24.          perror("open");
  25.          exit(1);
  26.      }
  27.      while(1)
  28.     {
  29.       memset(buf_r,0,sizeof(buf_r));
  30.       if((nread=read(fd,buf_r,100))==-1)
  31.       {
  32.           if(errno==EAGAIN)
  33.                printf("no data yet\n");
  34.       }
  35.       printf("read %s from FIFO\n",buf_r);
  36.       sleep(1);
  37.     }
  38.    pause();
  39.    unlink(FIFO);
  40. }
复制代码


 楼主 | 2019-3-25 13:28 | 显示全部楼层
  1. fifo_write .c
  2. #include<sys/types.h>
  3. #include<sys/stat.h>
  4. #include<errno.h>
  5. #include<fcntl.h>
  6. #include<stdio.h>
  7. #include<stdlib.h>
  8. #include<string.h>
  9. #define FIFO_SERVER  "/home/lm/myfifo"
  10. main(int argc,char** argv)
  11. {
  12.      char  w_buf[100];
  13.      int fd;
  14.      int nwrite;
  15.      fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
  16.      if(argc==1)
  17.      {
  18.          printf("please send something\n");
  19.          exit(-1);
  20.      }
  21.     strcpy(w_buf,argv[1]);
  22.      if((nwrite=write(fd,w_buf,100))==-1)
  23.       {
  24.           if(errno==EAGAIN)
  25.           printf("the FIFO has not been read yet,please try later\n");
  26.       }
  27.       else
  28.       printf("write %s to the FIFO\n",w_buf);   
  29. }
复制代码


 楼主 | 2019-3-25 13:28 | 显示全部楼层
信号通信
产生信号的条件:
01. 用户按某些按键。
02. 硬件异常,产生信号。
03. 可以使用kill函数将信号发送给另一个进程。
04. 用户可以使用kill命令将信号发送给其它进程
 楼主 | 2019-3-25 13:29 | 显示全部楼层
几个常见的信号:
SIGHUP:从终端上发出的结束信号。
SIGINT:来自键盘中的中断信号。
SIGKILL:该信号结束接收信号进程。
SIGTERM:kill命令发出的信号。
SIGSTOP:来自键盘或者调试程序的停止执行信号。
 楼主 | 2019-3-25 13:29 | 显示全部楼层
信号处理:
1.忽略次信号,大多数信号都按此种方式进行,有两种信号不能忽略:SIGKILL 和SIGSTOP,这两种信号向超级用户提供了一种终止或者停止进程的方法。
2.执行用户希望的动作。
   通知内核在某种信号发生时,调用一个用户函数。在用户函数中,执行用户希望的处理。
3.执行系统默认动作。
   对于多数信号,系统默认的动作是终止该进程。
 楼主 | 2019-3-25 13:36 | 显示全部楼层
信号发送:
发送函数主要有 Kill 和 raise
区别:Kill既可以向自身发送信号,也可以向其他进程发送信号。与Kill函数不同的是,raise函数是向进程自身发送信号。
#include<sys/types.h>
#include<signal.h>
int kill (pid_t pid,int signo)
int raise (int signal)
 楼主 | 2019-3-25 13:36 | 显示全部楼层
Alarm函数
该函数可以设置一个时间值(闹钟时间),到设置的时间到了,将会产生SIGNAL信号。如果不捕捉此信号,则默认动作是终止该进程。
#include<unistd.h>
unsigned int alarm(unsigned int seconds)
Seconds: 经过指定秒后将会产生信号。
| 2019-3-25 17:09 | 显示全部楼层
学习下!很不错的分享帖。
| 2019-3-25 22:22 | 显示全部楼层
看完不会啊。
 楼主 | 2019-3-25 22:27 | 显示全部楼层
frfgfvfd 发表于 2019-3-25 17:09
学习下!很不错的分享帖。

不客气哈,一起学习
 楼主 | 2019-3-25 22:27 | 显示全部楼层

总结性的东西,也是很难理解的
 楼主 | 2019-3-25 22:27 | 显示全部楼层

多注重实践,多写代码哈
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

快速回复 返回顶部 返回列表