linux进程和进程通信编程
Posted 小阿宁的猫猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux进程和进程通信编程相关的知识,希望对你有一定的参考价值。
What makes the desert beautiful is that somewhere it hides a well.
沙漠之所以美丽,是因为在它的某个角落隐藏着一口井.
linux进程和进程通信编程(2)
进程间通信
1.管道通信
进程A和进程B是应用层的, 不能直接通信
管道就用于它们之间的通信, 管道存在于内核
不管有名还是无名, 只要管道里面没有内容, 使用read函数就会被阻塞
(1)有名管道
用于任何两个进程都可以
相关程序21write.c , 21read.c
mkfifo
//头文件
#include <sys/stat.h>
#include <unistd.h>
要一边写一边读, 才能读到
21write.c , 21read.c代码
21write.c
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> //用于close,read,write,fork
int main(int argc, char *argv[])
char buf[32] = 0;
int fd;
int ret;
if (argc < 2)
printf("输入fifo文件名:\\n"); //输入参数太少了,就给提示
printf("argc:%d\\n", argc);
else if (argc = 2)
printf("argc:%d\\n", argc);
if (access(argv[1], F_OK) == -1)
// access用于判断是否存在键盘输入的那个fifo文件
ret = mkfifo(argv[1], 0666); //如果不存在的话,就创建一个管道文件
if (ret == -1)
printf("出错了");
else
printf("管道建好了");
fd = open(argv[1], O_WRONLY);
write(fd, "hello111", 8);
close(fd);
21read.c
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> //用于close,read,write,fork
int main(int argc, char *argv[])
char buf[32] = 0;
int fd;
int ret;
if (argc < 2)
printf("输入fifo的文件名:\\n"); //输入参数太少了,就给提示
else if (argc = 2)
fd = open(argv[1], O_RDONLY);
read(fd, buf, 32);
printf("buf:%s\\n", buf);
close(fd);
(2)无名管道
用于父子进程
相关程序20.c
无名管道要在子进程之前创建
如果父进程阻塞, 程序会一直卡着
父进程写了,子进程就可以读出来
20.c代码
//无名管道
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于pid_t
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h> //用于close,read,write,fork
int main() //不含参数
char buf[32]=0;
int fd[2]; //定义管道两端的描述符,有两个
pipe(fd); //创建管道
printf("fd[0]:%d\\n",fd[0]); //打印读端的fd
printf("fd[1]:%d\\n", fd[1]); //打印写端的fd
pid_t pid; //定义一个pid来接收fork的返回值
pid = fork();
if (pid < 0)
printf("创建失败");
//父进程
if (pid > 0)
write(fd[1],"hello",5);
//子进程
if (pid == 0)
close(fd[1]); //关闭写端,只用读
read(fd[0],buf,32);
printf("buf:%s\\n",buf);
close(fd[0]);
2.信号通信
具体用到哪个信号 , 上网查就行
(1)信号发送
//头文件
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
raise
用于自己给自己发信号
相关程序22.1.c
22.1.c代码
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main()
printf("raise之前\\n");
raise(9); // raise表示自己给自己发的信号,是不能被捕获的,里面的9表示终止进程
printf("raise之后\\n");
kill
用于kill进程, 和kill命令作用一样
相关程序22-2.c
用22-2.c去杀死22-3.c的进程
22-2.c,22-3.c代码
22-2.c
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main(int argc, char *argv[])
pid_t pid;
int sig;
if(argc<3)
printf("输入被操作的进程pid和信号种类\\n");
sig=atoi(argv[2]);
pid = atoi(argv[1]);
kill(pid,sig);
22-3.c
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main()
while(1)
sleep(1);
printf("hh\\n");
alarm
类似于设置一个闹钟,时间到了就kill进程
相关程序22-4.c
22-4.c代码
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main()
int i;
alarm(4); //表示在第4s时杀死进程
while (1)
sleep(1);
i++;
printf("i:%d\\n",i);
(2)信号接收
一个进程要长时间运行才能接收信号
比如用while(1) , sleep(x)(在x秒内一直运行) , pause(一直睡眠)
在进程运行时 , 按ctrl+c , 输kill, 进程就可以接收到这些信号了
用pause
用于让进程运行到一半进入休眠状态 , 会一直休眠, 用signal或ctrl+c退出
相关程序22-5.c
22-5.c代码
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main()
printf("pause之前\\n");
pause(); // pause表示进入休眠
printf("pause之后\\n");
(3)信号处理
默认 (终止) , 忽略 , 捕获
用signal
相关程序22-6.c
//头文件
#include <signal.h>
默认
signal(SIGINT,SIG_DFL);
//SIGINT表示ctrl+c,SIG_DFL表示执行ctrl+c的默认操作,就是终止
忽略
signal(SIGINT,SIG_IGN);
//SIGINT表示ctrl+c,SIG_IGN表示忽略ctrl+c这个信号
捕获
signal(SIGINT,myfun);
//捕捉SIGINT这个信号,然后执行myfun里面的代码
//比如按ctrl+c,就执行另一个循环
22-6.c代码
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
// void fun(int sig)
// if(sig==SIGINT)
// while (1)
//
// printf("hei hei\\n");
// sleep(2);
//
//
//
int main()
// signal(SIGINT,SIG_IGN); //忽略
// signal(SIGINT, SIG_DFL); //默认
// signal(SIGINT, fun); //执行新的函数
while (1)
printf("hh\\n");
sleep(2);
3.共享内存
用于进程间通信
创建共享内存
shmget
相关程序24-1.c
//头文件
#include <sys/ipc.h>
#include <sys/shm.h>
使用宏作为key值
使用ftok返回值作为key值
24-1.c代码
//创建共享内存,使用宏作为key值
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/ipc.h>//用于shmget
#include <sys/shm.h>
#include <sys/types.h>
int main()
int id;
id = shmget(IPC_PRIVATE, 1024, 0777); // IPC_PRIVATE 使用宏作为key值
if (id < 0)
printf("共享内存创建失败\\n");
else
printf("id:%d\\n", id);
shmat
用于把内核里的共享内存映射到用户空间
shmdt
将共享内存映射的地址删除
shmctl
删除内核里面的共享内存地址
以上是关于linux进程和进程通信编程的主要内容,如果未能解决你的问题,请参考以下文章
Socket详解-Linux Socket编程(不限Linux)