上一篇是创建文件,然后再映射到内存,再fork子进程,实现IPC。现在使用匿名内存映射
(1)使用/dev/zero文件。
(2)形式上没有文件。
先看第一种,由于/dev/zero本来已经存在,因此open的时候不需要第三个参数,第二个参数指定为O_RDWR即可。
#include
#include
#include
#include
#include
#include
#include
struct file_content
{
sem_t st;
void *pv;
} file_content;
#define NINT 16
#define FILE_ "/dev/zero"// 映射文件
int
main (int argc, char *argv[])
{
int fd;
struct file_content *pfc;
//打开文件
fd = open (FILE_, O_RDWR );
if (fd == -1)
{
printf ("file open failed!\n");
exit (2);
}
//内存映射
pfc =
mmap (NULL, sizeof (file_content) + sizeof (int) * NINT,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// 关闭文件
close (fd);
if (pfc == MAP_FAILED)
{
printf ("map failed!\n");
exit (3);
}
sem_init (&(pfc->st), 1, 1);//信号量初始化为1,用于互斥
pfc->pv = (void *) ((char *) pfc + sizeof (struct file_content)); // pv指向结构体下一个字节的地址
printf ("结构体地址:\t\t%x\n结构体下一位置地址:\t\t%x\n", (int)pfc, (int)pfc->pv);
setbuf(stdout,NULL); // 不加上这句的话,可能输出会卡在那里!
if (fork () == 0)//子进程
{
int i;
while (1)
{
sem_wait (&(pfc->st));
printf ("Child process\n");
int *p = pfc->pv;
for (i = 0; i < NINT; i++)
{
p[i] = 2 * i;
}
/*
for (i = 0; i < NINT; i++)
{
printf ("%d ", p[i]);
}
printf ("\n"); */
sem_post (&(pfc->st));
usleep(2000);
}
}
else// 父进程
{
int i;
while (1)
{
sem_wait (&(pfc->st));
printf ("Father process\n");
int *p = pfc->pv;
for (i = 0; i < NINT; i++)
{
p[i] = 3 * i;
}
/*
for (i = 0; i < NINT; i++)
{
printf ("%d ", p[i]);
}
printf ("\n");
*/
sem_post (&(pfc->st));
usleep(2000);
}
}
if (munmap (pfc, sizeof (file_content) + sizeof (int) * NINT) == -1)
{
printf ("ummap!\n");
exit (2);
}
return 0;
}
第二种,就是fd的位置用-1,然后呢,根本不打开任何文件。选项由MAP_SHARED变为MAP_SHARED|MAP_ANON。
#include
#include
#include
#include
#include
#include
#include
struct file_content
{
sem_t st;
void *pv;
} file_content;
#define NINT 16
#define FILE_ "/dev/zero"// 映射文件
int
main (int argc, char *argv[])
{
struct file_content *pfc;
//内存映射
pfc =
mmap (NULL, sizeof (file_content) + sizeof (int) * NINT,
PROT_READ | PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
if (pfc == MAP_FAILED)
{
printf ("map failed!\n");
exit (3);
}
sem_init (&(pfc->st), 1, 1);//信号量初始化为1,用于互斥
pfc->pv = (void *) ((char *) pfc + sizeof (struct file_content)); // pv指向结构体下一个字节的地址
printf ("结构体地址:\t\t%x\n结构体下一位置地址:\t\t%x\n", (int)pfc, (int)pfc->pv);
setbuf(stdout,NULL); // 不加上这句的话,可能输出会卡在那里!
if (fork () == 0)//子进程
{
int i;
while (1)
{
sem_wait (&(pfc->st));
printf ("Child process\n");
int *p = pfc->pv;
for (i = 0; i < NINT; i++)
{
p[i] = 2 * i;
}
/*
for (i = 0; i < NINT; i++)
{
printf ("%d ", p[i]);
}
printf ("\n"); */
sem_post (&(pfc->st));
usleep(2000);
}
}
else// 父进程
{
int i;
while (1)
{
sem_wait (&(pfc->st));
printf ("Father process\n");
int *p = pfc->pv;
for (i = 0; i < NINT; i++)
{
p[i] = 3 * i;
}
/*
for (i = 0; i < NINT; i++)
{
printf ("%d ", p[i]);
}
printf ("\n");
*/
sem_post (&(pfc->st));
usleep(2000);
}
}
if (munmap (pfc, sizeof (file_content) + sizeof (int) * NINT) == -1)
{
printf ("ummap!\n");
exit (2);
}
return 0;
}