题目:
(如:进程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;
}