第15章 进程间通信

几种方式
●talk命令
 功能:talk可以同时等待两个文件描述符的输入,读取字符并将它们写到目的地。
 实现:不能像下面这样,因为read会阻塞直到有输入,可能在第一个read处就挂起。使用非阻塞的方式可以工作,但是占用太多处理器时间。因为每次调用read都是一个系统调用,程序就必须回到内核模式工作,在等待一个字符来之前可能切换上千次。
在这里插入图片描述

●select系统调用:允许程序挂起,并等待从不止一个文件描述符的输入。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/* selectdemo.c : watch for input on two devices AND timeout
 *         usage: selectdemo dev1 dev2 timeout
 *        action: reports on input from each file, and 
 *                reports timeouts
 */

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

#define oops(m,x) { perror(m); exit(x); }
void showdata(char*,int);

int main(int ac, char *av[])
{
	int    fd1, fd2;           /* the fds to watch      */
	struct timeval timeout;    /* how long to wait      */
	fd_set readfds;            /* watch these for input */
	int    maxfd;		   /* max fd plus 1	    */
	int    retval;		   /* return from select    */
	if ( ac != 4 ){
		fprintf(stderr,"usage: %s file file timeout", *av);
		exit(1);
	}

	/** open files **/
	if ( (fd1 = open(av[1],O_RDONLY)) == -1 )
		oops(av[1], 2);
	if ( (fd2 = open(av[2],O_RDONLY)) == -1 )
		oops(av[2], 3);
	maxfd = 1 + (fd1>fd2?fd1:fd2);

	while(1) {
		/** make a list of file descriptors to watch **/
		FD_ZERO(&readfds);	   /* clear all bits  */
		FD_SET(fd1, &readfds);     /* set bit for fd1 */
		FD_SET(fd2, &readfds);     /* set bit for fd2 */

		/** set timeout value **/
		timeout.tv_sec = atoi(av[3]);  /* set seconds */
		timeout.tv_usec = 0;           /* no useconds */

		/** wait for input **/
		retval = select(maxfd,&readfds,NULL,NULL,&timeout);
		if( retval == -1 )
			oops("select",4);
		if ( retval > 0 ){
			/** check bits for each fd **/
			if ( FD_ISSET(fd1, &readfds) )
				showdata(av[1], fd1);
			if ( FD_ISSET(fd2, &readfds) )
				showdata(av[2], fd2);
		}
		else
			printf("no input after %d seconds\n", atoi(av[3]));
	}
}
void showdata(char *fname, int fd)
{
	char buf[BUFSIZ];
	int  n;

	printf("%s: ", fname, n);
	fflush(stdout);
	n = read(fd, buf, BUFSIZ);
	if ( n == -1 )
		oops(fname,5);
	write(1, buf, n);
	write(1, "\n", 1);
}

●通过文件的进程间通信
在这里插入图片描述

●命名管道
 通常管道只能连接相关的进程,而使用命名管道可以连接不相关的进程,并且可以独立于进程存在
在这里插入图片描述
在这里插入图片描述
●共享内存:共享内存段对于进程而言,就类似于共享变量对于线程一样。
在这里插入图片描述
在这里插入图片描述
共享内存时间服务器代码,客户改成读内存

/* shm_ts.c : the time server using shared memory, a bizarre application  */

#include	<stdio.h>
#include	<sys/shm.h>
#include	<time.h>

#define	TIME_MEM_KEY	99			/* like a filename      */
#define	SEG_SIZE	((size_t)100)		/* size of segment	*/
#define oops(m,x)  { perror(m); exit(x); }

main()
{
	int	seg_id;
	char	*mem_ptr, *ctime();
	long	now;
	int	n;

	/* create a shared memory segment */

	seg_id = shmget( TIME_MEM_KEY, SEG_SIZE, IPC_CREAT|0777 );
	if ( seg_id == -1 )
		oops("shmget", 1);

	/* attach to it and get a pointer to where it attaches */

	mem_ptr = shmat( seg_id, NULL, 0 );
	if ( mem_ptr == ( void *) -1 )
		oops("shmat", 2);

	/* run for a minute */
	for(n=0; n<60; n++ ){
		time( &now );			/* get the time	*/
		strcpy(mem_ptr, ctime(&now));	/* write to mem */
		sleep(1);			/* wait a sec   */
	}
		
	/* now remove it */
	shmctl( seg_id, IPC_RMID, NULL );
}

如何选择
在这里插入图片描述
在这里插入图片描述
进程间访问共享资源
●文件锁
进程可以忽略锁机制
在这里插入图片描述
●信号量
信号量是一个内核变量,可以被系统中的任何进程访问,进程间可以使用这个变量来协调对于共享内存和其他资源的访问。
在这里插入图片描述

纵观IPC:各种方式的特点,见书490

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值