18.8.17记录 part 1

****************进程间通信*******************

#目的
1.数据传输
2.资源共享
3.通知事件
4.进程控制

#发展
1.UNIX进程间通信
2.基于System V进程间通信(常用)
3.POSIX进程间通信(最新)

#POSIX表示可移植操作系统接口

#分类
1.管道(pipe)和有名管道(FIFO)
2.信号(signal)
3.消息队列
4.共享内存
5.信号量
6.套接字(socket)

#管道通信
    管道时单向的、先进先出。
    一个进程再管道的尾部写入数据
    另一个进程从管道的头部读出数据
    数据被一个进程读出后,将被从管道中删除    
    进程试图读空管道时,进程将阻塞。

1.无名管道
    用于父进程和子进程间的通信
2.有名管道
    后者可用于运行于同一系统中的任意两个进程间的通信

#无名管道创建
    int pipe(int filedis[2])
    filedis[0]用于读管道
    filedis[1]用于写管道

/*************************************************************************
    > File Name: pipe.c
    > Author: ma6174
    > Mail: ma6174@163.com 
    > Created Time: 2018年08月17日 星期五 09时30分08秒
 ************************************************************************/

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

void ReadData(int fd)
{
	int ret;
	char buf[32] = {0};
	while(1)
	{

		ret = read(fd, buf, sizeof(buf));
		if( -1 == ret )
		{
			perror("read");
			exit(1);
		}

		if(	!strcmp(buf,"bye"))
		{
			break;
		}

		printf("read from pipe:%s\n",buf);

		memset(buf, 0, sizeof(buf));

	}

	close(fd);

}

void WriteData(int fd)
{
	int ret;
	char buf[32] = {0};

	while(1)
	{
		scanf("%s",buf);

		ret = write(fd, buf, strlen(buf));
		if( -1 == ret )
		{
			perror("write");
			exit(1);
		}

		if( !strcmp(buf,"bye"))
		{
			break;
		}

		memset(buf, 0 ,sizeof(buf));
	}

	close(fd);

}

int main()
{
	int ret, fd[2] = {0};

	pid_t pid;

	ret = pipe( fd );
	if(-1 == ret )
	{
		perror("pipe");
		exit(1);
	}

	pid = fork();
	if( -1 == pid )
	{
		perror("fork");
		exit(1);
	}

	else if( 0 == pid )
	{
		close(fd[1]);

		ReadData(fd[0]);
	}
	else 
	{
		close(fd[0]);

		int status;
		
		WriteData(fd[1]);

		wait(&status);
	}
return 0;
}

#有名管道的创建:

注意:管道名称为:“fifo.tmp”,此项操作关系到内核,所以需要在home目录或根目录下操作。

创建用于写的文件:

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

int main()
{
	int ret;
	int fd;
	char buf[64]={0};

	fd = open("fifo.tmp", O_WRONLY );
	if( -1 == ret )
	{
		perror("open");
		exit(1)
	}

	while(1)
	{
		scanf("%s",buf);
		ret = write(fd, buf, strlen(buf));
		if( -1 == ret )
		{
			perror("read");
			exit(1);
		}

		if( !strcmp(buf, "bye") )
		{
			break;
		}

		memset(buf, 0, sizeof(buf));
	}

	close(fd);

return 0;
}

创建用于读的文件:

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

int main()
{
	int ret;
	int fd;
	char buf[64] = {0};

	ret = mkfifo("fifo.tmp",666);
	if( -1 == ret )
	{
		perror("mkfifo");
		exit(1);
	}
	
	fd = open("fifo.tmp", O_RDONLY );
	if( -1 == ret )
	{
		perror("open");
		exit(1);
	}

	while(1)
	{
		ret = read(fd, buf, sizeof(buf));
		if( -1 == ret )
		{
			perror("read");
			exit(1);
		}

		if( !strcmp(buf, "bye") )
		{
			break;
		}
		
		printf("%s\n",buf);

		memset(buf, 0, sizeof(buf));

	}

	close(fd);

	unlink("fifo.tmp");

return 0;
}

#信号通信
信号机制是Unix系统中最为古老的进程间通信机制,很多条件可以产生一个信号:
1.当用户按某些按键时,产生信号
2.硬件异常产生信号

#alarm(闹钟):
    int alarm( int seconds)

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

void print()
{
	alarm(1);

	printf("hello\n");

}

int main()
{
	alarm(1);

	signal( SIGALRM, print );

	while(1);

	return 0;
}

#消息队列
创建消息队列(msgget)
进程A用来发送数据(msgsnd)
进程B用来接收数据(msgrcv)

 

创建用于发送的消息队列:

注意:由于share文件夹里的权限不够,此项操作关系到内核,所以只能在根目录或home目录里操作。

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>

#define MSGKEY 2048

struct msgbuf 
{

	long mtype;     /* message type, must be > 0 */
	char mtext[64];  /* message data */
};

int main()
{
	struct msgbuf mbuf;
	int ret;
	int msgid;

	msgid = msgget( MSGKEY,IPC_CREAT | IPC_EXCL );
	if( -1 == msgid )
	{
		perror("msgget");
		exit(1);
	}

	while(1)
	{
		memset(&mbuf, 0, sizeof(mbuf));

		mbuf.mtype = 1;
		scanf("%s",mbuf.mtext);

		ret = msgsnd( msgid, &mbuf, sizeof(mbuf.mtext), 0 );
		if( -1 == ret )
		{
			perror("msgsnd");
			exit(1);
		}

		if( !strcmp(mbuf.mtext,"bye") )
		{
			break;
		}

	}
	
	msgctl(msgid, IPC_RMID, NULL);
	return 0;
}

 

创建用于接受的消息队列:

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>

#define MSGKEY 2048

struct msgbuf 
{

	long mtype;     /* message type, must be > 0 */
	char mtext[64];  /* message data */
};

int main()
{
	struct msgbuf mbuf;
	int ret;
	int msgid;

	msgid = msgget( MSGKEY, 0 );
	if( -1 == msgid )
	{
		perror("msgget");
		exit(1);
	}

	while(1)
	{
		memset(&mbuf, 0, sizeof(mbuf));

		mbuf.mtype = 1;

		ret = msgrcv( msgid, &mbuf, sizeof(mbuf.mtext), 1, 0 );
		if( -1 == ret )
		{
			perror("msgsnd");
			exit(1);
		}

		if( !strcmp(mbuf.mtext,"bye") )
		{
			break;
		}
		printf("%s\n",mbuf.mtext);
	}
	
	msgctl(msgid, IPC_RMID, NULL);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值