进程间通信-信号-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);
}


image

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;
}

image

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");
}

image

posted @ 2022-11-13 18:29  李兴昕  阅读(73)  评论(0编辑  收藏  举报