1)socket:经常遇到,不讲了
2)信号:使用kill发送信号,signal,settimer等系统调用都能对另一个进程发送信号,达到了进程间通信的目的。
kill(p1,16); /*向进程号为p1的进程 发中断信号16*/
signal(SIGINT,go); /*接收到SIGINT信号后,转go函数去处理它*/
3)共享内存:使用mmap系统调用能够做到共享内存,mmap的使用方式是以fd为入参,两个进程都打开一个文件名,并用mmap将这个fd映射到各自的进程环境,使用mmap反射回来的虚拟地址直接进行读写。
项目中曾经,在系统启动时内核创建一个内存块,保存printk缓冲区,插入一个ko在需要的时候获取这个缓冲区地址,并拷贝到用户空间,在需要时,使用mmap进行进程间的通讯获取到这个地址中的值。
fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
flength = lseek(fd, 1, SEEK_END);
write(fd, "\0", 1); /* 在文件最后添加一个空字符,以便下面printf正常工作 */
lseek(fd, 0, SEEK_SET);
start_addr = 0x80000;
mapped_mem = mmap(start_addr, flength, PROT_READ|PROT_WRITE, //允许写入
MAP_SHARED, //允许其它进程访问此内存区域
fd, 0);
4)消息队列:没有使用消息队列处理过进程间的通信。使用过类似消息的数组,处理过线程之间的数据共享。
5)信号量:没用过。
6)管道:pipe系统调用,数据只能单向流动,只能在亲缘关系的进程间流动。
项目中使用过无名管道,用来在c语言中调用shell脚本获得脚本的返回值。使用system系统调用执行脚本获得返回值,或者使用fork+exec系统调用新建子进程执行脚本。子进程中的返回值通过pipe返回给父进程。从而使得父进程能够获得子进程的返回值。
int filedes[2];
char buf[80];
pid_t pid;
pipe( filedes );
if ( (pid=fork()) > 0 )
{
printf( "This is in the father process,here write a string to the pipe.\n" );
char s[] = "Hello world , this is write by pipe.\n";
write( filedes[1], s, sizeof(s) );
close( filedes[0] );
close( filedes[1] );
}
else
{
printf( "This is in the child process,here read a string from the pipe.\n" );
read( filedes[0], buf, sizeof(buf) );
printf( "%s\n", buf );
close( filedes[0] );
close( filedes[1] );
}
waitpid( pid, NULL, 0 );