Linux下进程之间的通信
(1)、数据传输
一个进程需要将它的数据发送给另一个进程。
(2)、资源共享
多个进程之间共享同样的资源。
(3)、通知事件
一个进程需要向另一个或一组进程发送消息,通知
它们发生了某种事件。
(4)、进程控制
有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变。
二、进程间的通信方式:
管道是单向的、先进先出的,它把一个进程的输出和另一个进程的输入连接在一起。一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据。
数据被一个进程读出后,将被从管道中删除,其它读进程将不能再读到这些数据。管道提供了简单的流控制机制,进程试图读空管道时,进程将阻塞。同样,管道已经满时,进程再试图向管道写入数据,进程将阻塞。
(2).管道的创建
无名管道由pipe( )函数创建:
int pipe(int filedis[2]);
当一个管道建立时,它会创建两个文件描述符:filedis[0] 用于读管道,filedis[1] 用于写管道。
必须在系统调用fork()前调用pipe( ),否则子进程将不会继承文件描述符。
(3).命名管道:#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,将导致进程阻塞。
(2)、使用O_NONBLOCK:访问要求无法满足时不阻塞,立刻出错返回,errno是ENXIO。
(1)、当用户按某些按键时,产生信号。
(2)、硬件异常产生信号:除数为0、无效的存储访问等等。这些情况通常由硬件检测到,将其通知内核,然后内核产生适当的信号通知进程,例如,内核对正访问一个无效存储区的进程产生一个SIGSEGV信号。
(3)、进程用kill函数将信号发送给另一个进程。
(4)、用户可用kill命令将信号发送给其他进程。
#include <sys/types.h>
#include <signal.h>
int kill(pid_tpid,intsigno)
说明:kill向pid进程发送信号signo。调用成功返回0;否则,返回-1。其中pid参数值不同,接收进程不同,如表7.7所示。
#include <signal.h>
intraise(intsigno)
说明:raise()向进程本身发送信号,参数为即将发送的信号值。调用成功返回0;否则,返回-1。
#include <unistd.h>
unsigned int alarm(unsigned int seconds)
说明:alarm()专门为SIGALRM信号而设,在指定的时间seconds秒后,将向进程本身发送SIGALRM信号,又称为闹钟时间。进程调用alarm后,任何以前的alarm()调用都将无效。如果参数seconds为零,那么进程内将不再包含任何闹钟时间。如果调用alarm()前,进程中已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。
Linux主要有两个系统调用实现信号的接收,signal()和sigaction()。其中signal()在可靠信号系统调用的基础上实现, 是库函数。它只有两个参数,不支持信号传递信息,主要是用于前32种非实时信号的接收;
sigaction()是较新的函数,有三个参数,支持信号传递信息,sigaction()优于signal(),主要体现在前者支持信号带有参数。
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler));
说明:signal()负责接收指定信号signum,并进行相应处理。第一个参数指定信号的值,第二个参数指定针对前面信号值的处理,如果signal()调用成功,返回最后一次为接收信号signum而调用signal()时的handler值;失败则返回SIG_ERR。
#include <signal.h>
intsigaction(intsignum,conststructsigaction *act,structsigaction *oldact);
说明:sigaction()用于改变进程接收到特定信号后的行为。该函数的第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号。第二个参数是指向结构sigaction的一个实例的指针,在结构sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理;第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。
3.共享内存
共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。