Linux下进程间通信的几种主要手段如下
1:管道以及有名管道
管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
2:信号
信号是比较复杂的通信方式,用于通知接受进程有某种事情要发生,除了用于进程间通信外,进程还可以发送信号给进程本身;
3:报文队列(也叫消息队列)
消息队列是消息的链接表,包括POSIX消息队列和System V消息队列,有足够权限的进程可以向队列中添加消息,被赋予权限的进程则可以读走队列中的消息
4:共享内存
共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在不同的进程间复制
5:信号量。
又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是共享内存方式的进程间通信。本质上,信号量是一个计数器。它用来记录对某个资源的存取状况,
一般来说,为了获得共享资源,进程需要执行下列操作。
(1):测试控制该资源的信号两
(2):若此信号量的值为正,则允许使用该资源。进程将信号量减1
(3):若次信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量大于0,进程被唤醒,转入步骤(1)
(4):当进程不再使用一个信号量控制的资源时,信号量值加1.如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
6:套接字;
管道:
管道是单向的,先进先出的,没有结构的,固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入链接在一起。写进程在管道的尾端写入数据,读进程在管道的首端读出数据。数据读出后将从管道中移走,其他进程都不能再读到这些数据。管道提供了见到的流控制机制。进程试图
读空管道时,在有数据写入管道前,进程将一直阻塞。同样,当管道已经满时,进程再试图写管道时,其他进程从管道中移走
数据之前,写进程将一直阻塞
管道应用编程
要求:编写一个程序,实现以下功能
1:父进程使用系统调用pipe()建立一个管道
2:创建两个子进程,分别向两个管道各放下面一条消息结束
今天是2012年12月18日,我考过了场内!
今天是2012年12月18日,离期末考试还有14天,加油!
3:父进程从管道中分别接受两个子进程发来的消息并显示该消息,然后父进程结束,两个子进程的发送没有先后要求。
源码如下:
#include<unistd.h> //创建管道的头文件
#include<stdio.h>
#include<signal.h>//信号量的头文件
int main()
{
int p1,p2,fd[2]; //定义两个管道
char outpipe[100]; //定义管道的输出空间是多少
char inpipe1[100]="今天是2012年12月18日,我考过了场内!";
char inpipe2[100]="今天是2012年12月18日,离期末考试还有14天,加油!";
pipe(fd);
while((p1=fork())==-1);
if(p1==0)
{
lockf(fd[1],1,0); //将管道1全部上锁
write(fd[1],inpipe1,100); //将信息写入管道1
return 0; //返回值,正确返回0.错误返回1
}
else
{
while((p2=fork())==-1); // 判断第二个管道
if(p2==0)
{
lockf(fd[1],1,0);//将管道2全步上锁
write(fd[1],inpipe2,100);//将信息写入管道2
return 0;
}
else
{
wait(0);
read(fd[0],outpipe,100);
lockf(fd[1],0,0);//对管道1进行全部解锁
printf("父进程已经接受到了你的消息,恭喜你熊尧!\n");
printf("%s\n",outpipe);//打印出接受到的第一个消息
wait(0);
read(fd[0],outpipe,100);
lockf(fd[1],0,0);
printf("父进程已经接受到了你的消息,恭喜你熊尧!\n");
printf("%s\n",outpipe);//打印出接受到的第二个消息
return 0;
}
}
}
这个程序通过父进程使用系统调用pipe()新建一个无名管道,然后父进程创建两个子进程,之后父进程就一直等待子进程发送完消息。两个子进程通过父进程创建的管道,发送一定定义好的消息1和2然后退出。父进程则分别接受两个消息,先接受完第一个子进程的消息并显示,紧接着接受下一个进程发来的消息并显示
这个程序算是完整的做完了~