首页 > 系统相关 >20201317 LYX Linux进程间通信学习

20201317 LYX Linux进程间通信学习

时间:2022-11-13 13:22:45浏览次数:32  
标签:int printf LYX len 间通信 fd Linux line include

Linux进程间通信

1、匿名管道:pipe
2、命名管道:fifo
3、内存映射:mmap
4、信号

进程是程序运行资源分配的最小单位。每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。

1、匿名管道:pipe

pipe只能用于有血缘关系的进程进行单向通信。调用 pipe 函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端一个写端,然后通过 fd 参数传出给用户程序两个文件描述符, fd[0] 指向管道的读端, fd[1] 指向管道的写端。支持多端读或多端写,但不支持一端同时读写。看图会更加直观一点:
在这里插入图片描述

那么在使用pipe通信的时候可能会遇到以下的几种情况:

1. 当读管道时,如果管道中没有数据,则会阻塞,直到管道另一端写入数据。

2. 当写管道时,如果管道中已经满了,则会阻塞,直到管道另一端读出数据(可见读出数据时,管道中将不会保留该数据)。

3. 当管道写端关闭时,读端读完管道内的数据时,如果再次去读没有数据的管道会返回0,相当于读到了EOF。

4. 当管道读端关闭时,如果写端在写入数据时,产生SIGPIPE信号,写进程默认情况下会终止进程。

image-20221113120421158

image-20221113120505913

#include	<stdio.h>
#include    <stdlib.h>
#include	<unistd.h>

#define	oops(m,x)	{ perror(m); exit(x); }

int main(int ac, char **av)
{
	int	thepipe[2],			
		newfd,				
		pid;				

	if ( ac != 3 ){
		fprintf(stderr, "usage: pipe cmd1 cmd2\n");
		exit(1);
	}
	if ( pipe( thepipe ) == -1 )		
		oops("Cannot get a pipe", 1);

	if ( (pid = fork()) == -1 )			
		oops("Cannot fork", 2);

	if ( pid > 0 ){			
		close(thepipe[1]);	

		if ( dup2(thepipe[0], 0) == -1 )
			oops("could not redirect stdin",3);

		close(thepipe[0]);	
		execlp( av[2], av[2], NULL);
		oops(av[2], 4);
	}

	close(thepipe[0]);		

	if ( dup2(thepipe[1], 1) == -1 )
		oops("could not redirect stdout", 4);

	close(thepipe[1]);		
	execlp( av[1], av[1], NULL);
	oops(av[1], 5);
}

image-20221113120731602

#include	<stdio.h>

main( int ac, char *av[] )
{
	int	i;

	printf("Number of args: %d, Args are:\n", ac);
	for(i=0;i<ac;i++)
		printf("args[%d] %s\n", i, av[i]);

	fprintf(stderr,"This message is sent to stderr.\n");
}

image-20221113120941654

#include	<stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include	<unistd.h>

int main()
{
	int	len, i, apipe[2];	
	char	buf[BUFSIZ];		
	
	if ( pipe ( apipe ) == -1 ){
		perror("could not make pipe");
		exit(1);
	}
	printf("Got a pipe! It is file descriptors: { %d %d }\n", 
							apipe[0], apipe[1]);


	while ( fgets(buf, BUFSIZ, stdin) ){
		len = strlen( buf );
		if (  write( apipe[1], buf, len) != len ){	
			perror("writing to pipe");		
			break;					
		}
		for ( i = 0 ; i<len ; i++ )                     
			buf[i] = 'X' ;
		len = read( apipe[0], buf, BUFSIZ ) ;		
		if ( len == -1 ){				
			perror("reading from pipe");		
			break;
		}
		if ( write( 1 , buf, len ) != len ){		
			perror("writing to stdout");		
			break;					
		}
	}
}

image-20221113121104770

#include	<stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <unistd.h>


#define	CHILD_MESS	"I want a cookie\n"
#define	PAR_MESS	"testing..\n"
#define	oops(m,x)	{ perror(m); exit(x); }

main()
{
	int	pipefd[2];		
	int	len;			
	char	buf[BUFSIZ];		
	int	read_len;

	if ( pipe( pipefd ) == -1 )
		oops("cannot get a pipe", 1);

	switch( fork() ){
		case -1:
			oops("cannot fork", 2);
	
		case 0:			
			len = strlen(CHILD_MESS);
			while ( 1 ){
				if (write( pipefd[1], CHILD_MESS, len) != len )
					oops("write", 3);
				sleep(5);
			}
		
		default:		
			len = strlen( PAR_MESS );
			while ( 1 ){
				if ( write( pipefd[1], PAR_MESS, len)!=len )
					oops("write", 4);
				sleep(1);
				read_len = read( pipefd[0], buf, BUFSIZ );
				if ( read_len <= 0 )
					break;
				write( 1 , buf, read_len );
			}
	}
}

image-20221113121209723

#include	<stdio.h>
#include	<fcntl.h>

int main()
{
	int	fd ;
	char	line[100];

	fgets( line, 100, stdin ); printf("%s", line );
	fgets( line, 100, stdin ); printf("%s", line );
	fgets( line, 100, stdin ); printf("%s", line );

	close(0);
	fd = open("/etc/passwd", O_RDONLY);
	if ( fd != 0 ){
		fprintf(stderr,"Could not open data as fd 0\n");
		exit(1);
	}

	fgets( line, 100, stdin ); printf("%s", line );
	fgets( line, 100, stdin ); printf("%s", line );
	fgets( line, 100, stdin ); printf("%s", line );
}

image-20221113130147950

#include	<stdio.h>
#include    <stdlib.h>
#include	<fcntl.h>

//#define	CLOSE_DUP		
//#define	USE_DUP2	

main()
{
	int	fd ;
	int	newfd;
	char	line[100];

	fgets( line, 100, stdin ); printf("%s", line );
	fgets( line, 100, stdin ); printf("%s", line );
	fgets( line, 100, stdin ); printf("%s", line );

	fd = open("data", O_RDONLY);	
#ifdef CLOSE_DUP
	close(0);
	newfd = dup(fd);		
#else
	newfd = dup2(fd,0);		
#endif
	if ( newfd != 0 ){
		fprintf(stderr,"Could not duplicate fd to 0\n");
		exit(1);
	}
	close(fd);			

	fgets( line, 100, stdin ); printf("%s", line );
	fgets( line, 100, stdin ); printf("%s", line );
	fgets( line, 100, stdin ); printf("%s", line );
}

image-20221113130355621

#include	<stdio.h>
#include    <stdlib.h>
#include    <unistd.h>

int main()
{
	int	pid ;
	int	fd;

	printf("About to run who into a file\n");

	if( (pid = fork() ) == -1 ){
		perror("fork"); exit(1);
	}
	if ( pid == 0 ){
		close(1);				/* close, */
		fd = creat( "userlist", 0644 );		/* then open */
		execlp( "who", "who", NULL );		/* and run	*/
		perror("execlp");
		exit(1);
	}
	if ( pid != 0 ){
		wait(NULL);
		printf("Done running who.  results in userlist\n");
	}

	return 0;
}

image-20221113130546754

#include	<stdio.h>
#include    <stdlib.h>
#include    <unistd.h>

int main()
{
	int	pid ;
	int	fd;

	printf("About to run who into a file\n");

	if( (pid = fork() ) == -1 ){
		perror("fork"); exit(1);
	}
	if ( pid == 0 ){
		close(1);				/* close, */
		fd = creat( "userlist", 0644 );		/* then open */
		execlp( "who", "who", NULL );		/* and run	*/
		perror("execlp");
		exit(1);
	}
	if ( pid != 0 ){
		wait(NULL);
		printf("Done running who.  results in userlist\n");
	}

	return 0;
}

image-20221113130905293

标签:int,printf,LYX,len,间通信,fd,Linux,line,include
From: https://www.cnblogs.com/lyxhhz/p/16885834.html

相关文章

  • Linux纵深防护小记-系统的基本加固要求
    (目录)一、密码策略的强化authconfig--passminlen=12--passminclass=4--passmaxrepeat=2--update密码策略的修改将保存在/etc/security/pwquality.conf中。二、用......
  • Unix/Linux系统编程(TCP/IP和网络编程)
    TCP/IP协议TCP/IP是互联网的基础。TCP代表传输控制协议。IP代表互联网协议。目前有两个版本的IP,即IPv4和IPv6。IPv4使用32位地址,IPv6则使用128位地址。本节围绕IPv4进行......
  • Linux学习笔记(11)——进程管理与SELinux初探
    进程管理与SELinux初探进程管理与SELinux初探一、什么是进程1.1进程与程序(process&program)二、任务管理(jobcontrol)2.1什么是任务管理2.2jobcontrol的......
  • VMWare Linux系统磁盘扩容
    VMWareLinux系统磁盘扩容当我们在VMwareLinux虚拟机安装软件的时候,发现磁盘不够了,可以考虑给磁盘扩容,而不是重建虚拟机。1.修改磁盘容量点击编辑虚拟设置选择磁......
  • 计算机基础和Linux安装
    计算机基础和Linux安装1.计算机系统一个完整的计算机系统由硬件系统和软件系统两大部分组成。1.1冯·诺伊曼体系结构8个二进制位(bit,b)为1个字节(byte,B)。00000000......
  • L01.linux技术-bond-----交换机对应配置
    通常情况下,虚拟机的聚合模式bond4对应交换机的动态聚合(LACP),虚拟机的bond0对应交换机的静态聚合,虚拟机如果是主备模式,那么交换机不需要做聚合,只需要划分接口vlan即可。......
  • Linux 服务管理
    查看运行级别:runlevel修改运行级别:init运行级别默认运行级别:vim/etc/inittab服务自启动:指让服务在系统开机后随之启动服务查看服务自启动状态:chkconfig--list源码包......
  • L01.linux技术-bond
    一、bonding技术bonding(绑定)是一种linux系统下的网卡绑定技术,可以把服务器上n个物理网卡在系统内部抽象(绑定)成一个逻辑上的网卡,能够提升网络吞吐量、实现网络冗余、负......
  • 卡巴斯基发布2016年2季度DDoS报告:Linux僵尸网络“挑大梁”
     据外媒报道,Linux僵尸网络已占2016年2季度发起的“分布式拒绝服务攻击”(DDoS)中的70.2%。过去三个月时间里,安全研究人员发掘出了运行基于Linux的固件、能够发起DDoS攻击、......
  • 《Unix/Linux系统编程》第十三章学习笔记
    第13章TCP/IP和网络编程摘要本章论述了TCP/IP和网络编程,分为两个部分。第一部分论述了TCP/IP协议及其应用,具体包括TCP/IP栈、IP地址、主机名、DNS、IP数据包和路由器......