共享内存实现文件复制

题目:
(如:进程A 通过共享内存写 B进程从内存中读)
至少符合以下要求:
1).任意文件复制。(验证可以看是否能复制图片,复制的图片是否显示正常)
2).单个文件小于1M的复制。
共享内存:
进程A

//在共享内存写
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <time.h>
#define N 2048
//向共享内存中写内容
typedef struct
{
    pid_t pid;
    char buf[N];
    int tag;
} SHM;

void handler(int signo)
{
    //printf("get signal\n");
    return;
}

int main()
{
    int fd = -1;
    key_t key;
    int shmid;
    SHM *p;
    pid_t pid;

    if ((key = ftok(".", 'm')) < 0)
    {
        perror("fail to ftok");
        exit(-1);
    }

    signal(SIGUSR1, handler);               //  注冊一个信号处理函数
    if ((shmid = shmget(key, sizeof(SHM), 0666 | IPC_CREAT | IPC_EXCL)) < 0)
    {
        if (EEXIST == errno)                //  存在则直接打开
        {
            shmid = shmget(key, sizeof(SHM), 0666);

            p = (SHM *)shmat(shmid, NULL, 0);

            pid = p->pid;
            p->pid = getpid();
            kill(pid, SIGUSR1);
        }
        else//出错
        {
            perror("fail to shmget");
            exit(-1);
        }
    }
    else//成功
    {

        p = (SHM *)shmat(shmid, NULL, 0);
	memset(p,0,sizeof(SHM));
        p->pid = getpid();                  //  把自己的pid写到共享内存
        pause();
        pid = p->pid;                       //  得到读端进程的pid

    }
    printf("shmid : %d\n",shmid);
    printf("pid from read : %d\n",pid);
    int retData = 0;
    static int ret = 0;
    int outFd = -1;
    srand(time(0));
    fd = open("test.jpg", O_RDWR, 0666);
    while (1)
    {	
	sleep(1);
	retData = rand()%1537 + 512;
	printf("write to shm size: ");
	ret = read(fd,p->buf,retData);
	p->tag = ret;
	printf("%d\n",p->tag);
        //fgets(p->buf, N, stdin);            //  接收输入
        kill(pid, SIGUSR1);                 //  向读进程发SIGUSR1信号
        while((strlen(p->buf)!=0) && (ret!=0)); //等待读取进程读完内容
	if (ret == 0) break;
        //pause();                            //  堵塞,等待信号
	
    }
    shmdt(p);
    shmctl(shmid, IPC_RMID, NULL);          //  删除共享内存

    return 0;
}

进程B

//读取共享内存中的内容
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#define N 2048
//读共享内存的内容
typedef struct
{
    pid_t pid;
    char buf[N];  //共享内存内容
    int tag;	  //指定写入内容的大小
} SHM;

void handler(int signo)
{
    //printf("get signal\n");
    return;
}

int main()
{
    int fd = -1;
    key_t key;
    int shmid;
    SHM *p;
    pid_t pid;
    
    if ((key = ftok(".", 'm')) < 0)
    {
        perror("fail to ftok");
        exit(-1);
    }

    signal(SIGUSR1, handler);               //  注冊一个信号处理函数
    //创建共享内存
    if ((shmid = shmget(key, sizeof(SHM), 0666 | IPC_CREAT | IPC_EXCL)) < 0)
    {
        if (EEXIST == errno)                //  存在则直接打开
        {
            shmid = shmget(key, sizeof(SHM), 0666);

            p = (SHM *)shmat(shmid, NULL, 0);

            pid = p->pid;
            p->pid = getpid();
            kill(pid, SIGUSR1);
        }
        else//出错
        {
            perror("fail to shmget");
            exit(-1);
        }
    }
    else//成功
    {

        p = (SHM *)shmat(shmid, NULL, 0);
	memset(p,0,sizeof(SHM));
        p->pid = getpid();                  //  把自己的pid写到共享内存
        pause();
        pid = p->pid;                       //  得到读端进程的pid

    }
    printf("shmid : %d\n",shmid);
    printf("pid from write : %d\n",pid);
    fd = open("test4.jpg", O_CREAT|O_TRUNC|O_WRONLY,0777);
    
    int size=lseek(fd,0,SEEK_END);
    printf("file size: %d\n",size);
    printf("fd: %d\n",fd);
    while (1)
    {	
	pause();//堵塞,等待信号
	printf("read from shm size: %d\n", p->tag);
        //if (strcmp(p->buf, "quit\n") == 0) exit(0);//输入"quit结束"
	write(fd,p->buf,p->tag);
	memset(p->buf,0,sizeof(p->buf));  //清零
	
        kill(pid, SIGUSR1);//向写进程发SIGUSR1信号
	if(p->tag == 0) break;
	
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值