进程间通信

进程间通信(IPC)方式
管道:有名管道和无名管道
消息队列
信号量
共享内存
套接字

进程间通信的目的:
1、数据传输:
2、共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程一个第一时间看到
3、通知事件:一个进程需要向另一个或一组进程发送消息,通知他们发生了某种事件(如进程终止时通知父进程)
4、资源共享:多个进程之间共享同样的资源,未做到这一点,需要内核提供锁和同步机制。
5、进程控制

管道通信:无名管道:一端写,一端读
管道是半双工的,数据只能向一个方向流动
必须在系统调用fork()前调用pipe(),否则子进程将不会继承文件描述符
1如果管道的写端不存在,则认为已经读到数据末尾,改函数返回的读出字节数为0;
2如果写端存在时,如果请求的字节数目大于PIPE_BUF,则返回现有的管道数据字节数;如果不大于,则返回现有数据字节数,或请求字节数。

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

int main()
{
    int status;
    int fd[2];
    pid_t pid;

    if(-1==pipe(fd))
    {
	perror("error");
	exit(1);
    }
    pid = vfork();
    if(-1 == pid)
    {
	perror("fork error");
	exit(1);
    }
    if(0 == pid)
    {
   
	char buff[20]={0};
	printf("child\n");
	printf("please input:\n");
	scanf("%s",buff);
        write(fd[1],buff,strlen(buff)); 
	exit(0);
    }
    else
    {
	waitpid(pid,&status,0);
	char buffer[1024]={0};
	read(fd[0],buffer,20);
        printf("%s\n",buffer);
	printf("father\n");
    }
}

mode:O_WRONLY
O_RDONLY

有名管道 进程间相互输入输出

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#define FIFO "./test.txt"

int main()
{

    int i=0;
    pid_t pid;
    int info=mkfifo(FIFO,0666);
    int status;
    int fd;

    if(info<0)
    {
	perror("mkfifo error");
	exit(1);
    }

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

    if(0 == pid)
    {
	while(1)
	{
	fd = open(FIFO,O_WRONLY);
	char buf[25]={0};

	printf("child input1:\n");
	scanf("%s",buf);

	write(fd,buf,strlen(buf));
	memset(buf,0,sizeof(buf));
        sleep(1);

	fd = open(FIFO,O_RDONLY);
	read(fd,buf,20);
	printf("child speak to father: %s\n",buf);
	memset(buf,0,sizeof(buf));	
	}
	exit(0);
    }
    else
    {
	while(1)
	{
	fd = open(FIFO,O_RDONLY);
        char buffer[1024]={0};
	read(fd,buffer,12);
	printf("father speak to child: %s\n",buffer);
	memset(buffer,0,sizeof(buffer));

	fd = open(FIFO,O_WRONLY);
	printf("fahter input2:\n");
	scanf("%s",buffer);
	write(fd,buffer,strlen(buffer));
	memset(buffer,0,sizeof(buffer));
	sleep(1);
	}
  }
  return 0;
}

进程间通信

write.c

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

#define FIFO  "./test.txt"

int main()
{
    pid_t pid;
    char buffer[100];
    int ret;
   if((ret=mkfifo(FIFO,0644))<0)
    {
	if(ret==-1&&errno == EEXIST)
	{

	}
	else
	{
	    perror("make mkfifo error");
         	exit(1);
	}
    }
    
    int fd=open(FIFO,O_WRONLY);
    
    while(1)
	{
	memset(buffer,0,sizeof(buffer));
	scanf("%s",buffer);
	write(fd,buffer,strlen(buffer));
	}
    return 0;
  }
   

read.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<errno.h>
#define FIFO "./test.txt"

int main()
{
    pid_t pid;
    int ret;

    char buffer[100];

    if((ret=mkfifo(FIFO,0644))<0)
    {
	if(ret == -1 && errno == EEXIST)
	{

	}
	else
	{
	perror("error");
	exit(0);
	}
    }

    int  fd = open(FIFO,O_RDONLY);

    while(1)
    {
	memset(buffer,0,sizeof(buffer));
	read(fd,buffer,sizeof(buffer));
	printf("recv :%s\n",buffer);
	sleep(2);
    }
    return 0;
 }

2.信号:软中断(程序传输信息的媒介)
Ctrl+z:暂停信息
Ctrl+c:停止信号
Int kill(pid_t, int sig)
信号处理
sighandler_t signal(int signum, sighandler_t handler);
信号的编号 信号的处理机制
SIG_IGN:忽略信号
SIG_DFL:信号的直接处理

管道特点:
1传输数据量少,因此只适合小数据的传输
2 管道数据被读出时会自动删除
3 管道数据是以什么格式输出:结构化,非结构化和半结构化。

共享内存
无格式:
当数据量大且读写效率要求较高的时候(读写效率提高减少了进出内核的次数)
内核的实现原理:

在内存中开辟一块内存可以让多个进程共享(malloc)。
如果一个进程对于共享内存的内容进行了更改,其他进程都会受到影响。
一个共享内存的最大容量:shnmax。

Posix:POSIX表示可移植操作系统接口
系统V :
Mmap:mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。

开辟共享内存
int shmget(key_t key, size_t size, int shmflg);
共享内存键值:0
IPC_PRIVATE:共享内存的表示符
shmflg:IPC_CREAT
映射共享内存:shmat :
void *shmat(int shmid, const void *shmaddr, int shmflg);
(决定以什么方式来决定映射地址,通常为0)

Eg

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

struct data
{
    char dat[100];
};

int main()
{
    struct data *ptr;
    int shmid = shmget(1,sizeof(struct data),0666|IPC_CREAT);
    int status;
    if(-1 == shmid)
    {
	perror("shmget error");
        exit(0);
    }

    if(ptr==(void *)-1)
    {
	perror("shmat error");
	exit(1);
    }

    scanf("%s",ptr->dat);

    pid_t pid=vfork();

    if(-1 == pid)
    {
	perror("error");
	exit(0);
    }
    if(0==pid)
    {
	printf("child :%s\n",ptr->dat);
        scanf("%s",ptr->dat);
	exit(6);
    }
    else
    {
	pid = wait(&status);
	printf("father  %s\n",ptr->dat);
    }

    int shm = shmctl(shmid,IPC_RMID,NULL);
    if(-1==shm)
    {
	perror("shmtcl error");
	exit(2);
    }
    return 0;
}

共享内存的步骤:1进程调用shmget函数创建新的或获取已有的共享内存
2调用shmat函数将物理内存映射到自己的进程空间
3调用shmdt函数取消映射
4调用shmtl函数释放开辟的物理空间;

使用联合体判断cpu 大端小端

#include "stdio.h"
  union w
{
  int a;  //4 bytes
  char b; //1 byte
}c;
int main()
{
  c.a=1;
  if (c.b==1)
  printf("It is Little_endian!/n");
  else
  printf("It is Big_endian!/n");
  return 1;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

躺尸研究员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值