进程间通信

Linux常用的进程间通信方式有:

1、管道(pipe)和有名管道(FIFO)

2、信号(signal)

3、消息队列

4、共享内存

5、信号量

6、套接字

 

***********************************管道通信实例************************************

pipe只能用于父进程和子进程之间通信。

 

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include<string.h>

int main()
{
	int pipe_fd[2];					//管道描述符
	pid_t pid;						//进程描述符
	char buf_r[100];				//读取数据的缓冲区	
	char* p_wbuf;
	int r_num;						//read函数返回值
	
	memset( buf_r, 0, sizeof( buf_r ) );
	/*创建管道*/
	if( pipe( pipe_fd ) < 0 )
	{
		printf("pipe create error\n");
		return -1;
	}
	/**父进程向管道里写入数据,子进程读取父进程写入的内容**/
	/*创建子进程*/
	if( ( pid = fork() ) == 0 )			//子进程运行
	{
		printf("\n");
		close( pipe_fd[1] );			//子进程
		sleep(2);
		if( ( r_num = read( pipe_fd[0] ,buf_r, 100 ) ) >0  )//从管道头部读取数据
		{
			printf("  %d numbers read from the pipe is %s\n", r_num, buf_r );
		}
		close( pipe_fd[0] );
		exit(0);
	}
	else if( pid > 0 )								//父进程
	{
		close( pipe_fd[0] );						//关闭管道的读数据端
		if( write( pipe_fd[1], "Hello", 5 ) !=-1 )
			printf("parent write1 Hello!\n");
		if( write( pipe_fd[1], "Pipe", 5 ) != -1)
			printf("parent write2 Pipe!\n");
		close( pipe_fd[1] );						//关闭管道的写入端,
		sleep(3);
		waitpid( pid, NULL, 0);						//等待子进程结束
		exit(0);

	}
	return 0;

}


 

*****************************FIFO实例***********************************

FIFO可以用于同一系统上的任意两个进程间通信。

fifo_write.c

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/tmp/myfifo"

main(int argc,char** argv)
{
	int fd;
	char w_buf[100];
	int nwrite;
		
	/*打开管道*/
	fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
	
	if(argc==1)
	{
		printf("Please send something\n");
		exit(-1);
	}
	
	strcpy(w_buf,argv[1]);
	
	/* 向管道写入数据 */
	if((nwrite=write(fd,w_buf,100))==-1)
	{
		if(errno==EAGAIN)
			printf("The FIFO has not been read yet.Please try later\n");
	}
	else 
		printf("write %s to the FIFO\n",w_buf);
}


 

fifo_read.c

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"

main(int argc,char** argv)
{
	char buf_r[100];
	int  fd;
	int  nread;
	
	/* 创建管道 */
	if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
		printf("cannot create fifoserver\n");
	
	printf("Preparing for reading bytes...\n");
	
	memset(buf_r,0,sizeof(buf_r));
	
	/* 打开管道 */
	fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
	if(fd==-1)
	{
		perror("open");
		exit(1);	
	}
	while(1)
	{
		memset(buf_r,0,sizeof(buf_r));
		
		if((nread=read(fd,buf_r,100))==-1)
		{
			if(errno==EAGAIN)
				printf("no data yet\n");
		}
		printf("read %s from FIFO\n",buf_r);
		sleep(1);
	}	
	pause(); /*暂停,等待信号*/
	unlink(FIFO); //删除文件
}


 

*******************************信号通信实例********************************

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

void my_func(int sign_no)
{
	if(sign_no==SIGINT)
		printf("I have get SIGINT\n");
	else if(sign_no==SIGQUIT)
		printf("I have get SIGQUIT\n");
}
int main()
{
	printf("Waiting for signal SIGINT or SIGQUIT \n ");
	
	/*注册信号处理函数*/
	signal(SIGINT, my_func);
	signal(SIGQUIT, my_func);
	
	pause();
	exit(0);
}

 

****************************共享内存通信实例*************************************************

/*
**使用共享内存实现父进程和子进程之间的通信
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define PERM S_IRUSR|S_IWUSR

int main(char argc, char *argv[])
{
	int shmid;				//共享内存标识符
	char *p_addr, *c_addr;

	if( argc !=2 )
	{
		fprintf( stderr, "Usage:%s\n\a", argv[0] );
		exit(1);
	}
	/**创建共享内存*/
	if( ( shmid = shmget( IPC_PRIVATE, 1024, PERM) ) == -1 )
	{
		fprintf(stderr, "Create Share Memory Error:%\n\a", strerror(errno) );
		exit(1);
	}
	/*创建子进程*/
	if( fork() )					//父进程写
	{
		p_addr = shmat( shmid, 0, 0 );
		memset( p_addr, '\0', 1024 );
		strncpy( p_addr, argv[1], 1024 );
		wait(NULL);
		exit(0);
	}
	else						//子进程读
	{
		sleep(1);
		c_addr = shmat( shmid, 0, 0);
		printf("Client get %s\n", c_addr );
		exit(0);
	}
}


 

**************************消息队列通信实例****************************************

 

/*
**消息队列
*/
#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct msg_buf
    {
        int mtype;
        char data[255];
    };
 int main()
 {
	 key_t key;
	 int msgid;
	 int ret;
	 struct msg_buf msgbuf;

	 /*获得文件键值*/
	 key = ftok( "/tmp/msg", 'a' );
	 printf("key = [%x]\n", key);  

	 /**创建消息队列*/
	 msgid = msgget( key, IPC_CREAT|0666 );
	 if(msgid == -1 )
	 {
		 perror("msgget");
		 exit(1);
	 }
	 /*给消息队列中发送一条消息*/
	 msgbuf.mtype = getpid();					//填充msg_buf结构体
	 strcpy(msgbuf.data, "fang haha");
	 ret = msgsnd( msgid, &msgbuf, sizeof(msgbuf.data), IPC_NOWAIT );
	 if( ret == -1 )
	 {
		 perror("msgsnd");
		 exit(1);
	 }
	 /*从消息队列中读取消息*/
	 memset( &msgbuf, 0, sizeof(msgbuf) );
	 ret = msgrcv( msgid, &msgbuf, sizeof(msgbuf), getpid(), IPC_NOWAIT );
	 if( ret == -1 )
	 {
		 perror("msgrcv");
		 exit(1);
	 }
	 puts(msgbuf.data);

 }


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值