嵌入式开发第25天(无名管道,有名管道,信号)



进程间通信
管道(无名管道,有名管道)

信号 signal
system V IPC(共享内存,消息队列,信号量)


通信目的:共享资源、通知事件、数据传输、进程控制


-----------------------------------------------------------
管道:

无名管道:只能在亲缘进程中 半双工通信方式  fd[0]读端,fd[1]写

pipe()必须在fork()之前,才能保证亲缘进程使用同一个管道
在读与写端不使用时要用close关闭
读端是有阻塞的,会等到有数据写入才返回
如果写端关闭了,读会立刻返回
如果读端关闭了,在调用write时候内核会产生一个SIGPIPE(write:Broken pipe
如果管道里面的数据已经写满了,会产生阻塞,直到数据被读出,才能继续写入
无名管道的写操作不能保证数据的原子性(完整性)

对无名管道做文件操作:read()/write()/close()
   但是不能lseek,会返回失败
   pipe()打开并创建无名管道,已经设置好打开方式,不能更改。

   无名管道只存在于进程中,进程结束也随之消失


局限:只能在亲缘进程中,数据的完整性不能保证

对于管道不能在共享目录中去编译运行



pipe()无名管道
       #include

 int pipe(int fildes[2]);
返回值: 成功:0
失败:-1


int fildes[2];读写端的描述符


练习:在单进程中,创建一个管道,然后往管道里写端写入数据,然后从读端将数据读出来。



有名管道

有名管道:在任意两个进程间通信(fifo)
mkfifo
1、读端是有阻塞的,会等到有数据写稿才返回(读阻塞)
2、如果写端关闭了,读端的read出没有等待的必须,会直接pass
3、写端也会阻塞,管道里面已经写满了,产生阻塞(能够保证数据的原子性、完整性)


对有名管道的文件操作:

open   //有名管道 其实像一个文件一样,所以创建后,需要打开
read
write
close
lseek


mkfifo
#include
#include

int mkfifo(const char *pathname, mode_t mode);
返回值:  0:成功
-1:失败
const char *pathname:要创建的管道名
mode_t mode:指定创建的管道的访问权限


在创建有名管道,一个进程负责不断地写入,一个负责不断地接收


信号
信号:硬件上的中断有些类似
信号的产生:硬件产生 ctrl+c
  软件产生 段错误SIGSEGV SIGPIPE SIGCHLD
作用:直接进行用户空间进程和内核进程间的交互


相看当前系统的信号:kill -l


1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX


kill


      #include


       int kill(pid_t pid, int sig);
返回值: 成功:0
失败:-1
pid_t pid:进程PID
int sig:发送的信号//可以是信号的标号,出可以是信号名称




1、a.用pipe产生一个无名管道之后,再连续产生两个子进程A,B
   b.子进程A往管道写了一句hello后就退出了-------写fd[1];
   c.子进程B读到A写入的数据,再往管道中写入hello world---读fd[0]与fd[1];
   d.主进程读取最后管道中的数据并打印----读fd[0];



2、模拟简单的客户端和服务器端通信,用有名管道实现
需要两个管道文件
其中一个是客户端写入,服务器端读取,另一个服务器写入,客户端读取
客户端写入数据
服务器把读到的数据做简单处理后返回给客户,反之亦然

如客户端写入123456,服务器收到后,反馈给客户received:123456
客户端收到该反馈信息后,会和之前的信息确认,无误才发送下一个信息
两个进程遇到exit就结束。


























你可能感兴趣的:(日记)