进程间通信-信号-pipe-fifo
一、有名管道FIFO
1.在有名管道(named pipe或FIFO)提出后,管道(pipe)限制得到了克服。
- 值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。
- 它们不支持诸如lseek()等文件定位操作。
二、管道PIPE
管道是Linux中进程间通信的一种方式。这里所说的管道主要指无名管道,它具有以下特点:
-
它只能用于具有亲缘关系的进程之间的通信(也就是父子进程或者兄弟进程之间)。
-
它是一个半双工的通信模式,具有固定的读端和写端。需要双方通信时,需要建立起两个管道。
-
管道也可以看成是一种特殊的文件,对于它的读写也可以使用普通的read()和write()等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内核的内存空间中。
-
数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
三、SIGNAL
多任务操作系统环境﹣多进程:
-
同步关系:多进程为了完成同一个任务相互协作
-
互斥关系:不同进程为了争夺有限的系统资源,进入竞争状态
-
进程之间的互斥与同步关系存在的根源在于临界资源
-
临界资源是在同一个时刻只允许有限个(通常只有一个)进程可
-
以访问(读)或修改(写)的资源;
-
访问临界资源的代码叫做临界区,临界区本身也会成为临界资源。
-
信号量﹣解决进程之间的同步与互斥问题
-
称为信号量的变量
-
在该信号量下等待资源的进程等待队列
-
对信号量进行的两个原子操作( PV 操作)
1.sigactdemo.c
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#define INPUTLEN 100
void inthandler();
int main()
{
struct sigaction newhandler;
sigset_t blocked;
char x[INPUTLEN];
newhandler.sa_handler = inthandler;
newhandler.sa_flags = SA_RESTART|SA_NODEFER
|SA_RESETHAND;
sigemptyset(&blocked);
sigaddset(&blocked, SIGQUIT);
newhandler.sa_mask = blocked;
if (sigaction(SIGINT, &newhandler, NULL) == -1)
perror("sigaction");
else
while (1) {
fgets(x, INPUTLEN, stdin);
printf("input: %s", x);
}
return 0;
}
void inthandler(int s)
{
printf("Called with signal %d\n", s);
sleep(s * 4);
printf("done handling signal %d\n", s);
}
2.sigactdemo2.c
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
void sig_alrm( int signo )
{
/*do nothing*/
}
unsigned int mysleep(unsigned int nsecs)
{
struct sigaction newact, oldact;
unsigned int unslept;
newact.sa_handler = sig_alrm;
sigemptyset( &newact.sa_mask );
newact.sa_flags = 0;
sigaction( SIGALRM, &newact, &oldact );
alarm( nsecs );
pause();
unslept = alarm ( 0 );
sigaction( SIGALRM, &oldact, NULL );
return unslept;
}
int main( void )
{
while( 1 )
{
mysleep( 2 );
printf( "Two seconds passed\n" );
}
return 0;
}
3.sigdemo3.c
#include<stdio.h>
#include<string.h>
#include<signal.h>
#include<unistd.h>
#define INPUTLEN 100
int main(int argc, char *argv[])
{
void inthandler(int);
void quithandler(int);
char input[INPUTLEN];
int nchars;
signal(SIGINT, inthandler);//^C
signal(SIGQUIT, quithandler);//^\
do {
printf("\nType a message\n");
nchars = read(0, input, (INPUTLEN - 1));
if (nchars == -1)
perror("read returned an error");
else {
input[nchars] = '\0';
printf("You typed: %s", input);
}
}
while (strncmp(input, "quit", 4) != 0);
return 0;
}
void inthandler(int s)
{
printf(" Received signal %d .. waiting\n", s);
sleep(2);
printf(" Leaving inthandler \n");
}
void quithandler(int s)
{
printf(" Received signal %d .. waiting\n", s);
sleep(3);
printf(" Leaving quithandler \n");
}