linux多线程【8】mmap实现父子进程的共享内存通信,用信号量同步
2013-05-12 17:31
651 查看
1.创建文件。open,ftruncate
2.将文件映射到内存。内存首地址存放一个sem_t实现进程的互斥。mmap,sem_init
3.创建子进程。父子进程互斥地访问共享内存的内容。fork,sem_wait,sem_post
4.取消映射。munmap
由于需要同步或者互斥,因此需要sem_t,我们把他放在内存区的开头,那么真正可用的内存就是开头做一定偏移。维护一个指针,使指针
指向实际数据区。就定义一个结构体:
初始化时:
这样,st就是sem_t信号量。pv就是数据指针,比较方便!
另外,sem_t初始化时第二个参数设为1,表示用于进程间而不限于进程间的访问。
父子进程都是无线运行的,需要按ctrl+c退出:
2.将文件映射到内存。内存首地址存放一个sem_t实现进程的互斥。mmap,sem_init
3.创建子进程。父子进程互斥地访问共享内存的内容。fork,sem_wait,sem_post
4.取消映射。munmap
由于需要同步或者互斥,因此需要sem_t,我们把他放在内存区的开头,那么真正可用的内存就是开头做一定偏移。维护一个指针,使指针
指向实际数据区。就定义一个结构体:
struct file_content { sem_t st; void *pv; } file_content;
初始化时:
pfc->pv = (void *) ((char *) pfc + sizeof (struct file_content)); // pv指向结构体下一个字节的地址
这样,st就是sem_t信号量。pv就是数据指针,比较方便!
另外,sem_t初始化时第二个参数设为1,表示用于进程间而不限于进程间的访问。
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>
#include <syslog.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <semaphore.h>
struct file_content { sem_t st; void *pv; } file_content;
#define NINT 16
#define FILE_ "map_file" // 映射文件
#define FILE_MODE S_IRUSR | S_IWUSR // 打开文件的权限mode
int
main (int argc, char *argv[])
{
int fd;
struct file_content *pfc;
//打开文件
fd = open (FILE_, O_RDWR | O_CREAT, FILE_MODE);
if (fd == -1)
{
printf ("file open failed!\n");
exit (2);
}
//将文件变为256大小
ftruncate (fd, sizeof (file_content) + sizeof (int) * NINT);
//内存映射
pfc =
mmap (NULL, sizeof (file_content) + sizeof (int) * NINT,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (pfc == MAP_FAILED)
{
printf ("map failed!\n");
exit (3);
}
// 关闭文件
close (fd);
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;
}
父子进程都是无线运行的,需要按ctrl+c退出:
administrator@ubuntu:~/test$ ./sh 结构体地址: b7717000 结构体下一位置地址: b7717014 Father process Child process Father process Child process Father process Child process Father process Child process Father process
相关文章推荐
- 共享内存多进程间通信,进程间同步使用信号量来实现
- 共享内存多进程间通信,进程间同步使用信号量来实现
- 进程通信----共享内存以及mmap函数实现共享内存
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- 进程间共享内存(信号量实现同步)
- linux下的多进程通信(IPC)原理及实现方案(管道、队列、信号量、共享内存)
- [Linux管道和IPC]使用信号量和共享内存进行父子进程通信
- 进程通信----共享内存以及mmap函数实现共享内存
- 进程间共享内存(信号量实现同步)
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- 通过共享内存和信号量实现进程间的通信
- 利用共享内存,结合信号量的控制来实现服务器客户端的通信
- Linux\Unix IPC进程通信实例分析(一):共享内存通信---文件映射mmap方式
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped
- 通过信号量和共享内存实现h264码流在不同进程间传输
- IPC—进程间的通信(信号量,共享内存,消息队列)
- linux基于信号量同步的共享内存IPC实现
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转
- 通过共享内存,利用循环队列实现两个进程A,B之间的通信
- 进程通信之信号量限制共享内存