应用程序运行时的虚拟内存布局 - 进程 - 线程
2016-04-08 16:47
363 查看
每一个进程都是类似上图的内存分布
当进程fork一个子进程的时候, 子进程拷贝父进程当前的内存空间, 包括环境变量, 栈空间, 堆空间, 代码段, 数据段等等
所以在子进程调用exec类函数之前, 所有都是和父进程一样的
所有线程共享所属进程的环境变量和栈空间
进程间通信的数据结构是内核维护的, 独立于某一进程的。
进程间共享内存的使用
首先一个进程向内核申请共享内存空间, 一个key标识这块共享内存,返回一个id, 可以通过id获取该共享内存的内存地址
如果进程间有关系,比如父子进程, 那么子进程拷贝了父进程的栈空间, 可以直接使用这个id获取共享内存的内存地址
int shmget(key_t key, size_t size, int flag);
int shmid = shmget(IPC_PRIVATE, 2048, 0666);
struct info *infop = shmat(shmid, 0, 0);
如果进程间没有关系, 另一个进程只要想办法获取到id就可以使用了, 比如通过文件,或者其他手段
struct info *infop = shmat(shmid, 0, 0);
/** processA.c */ #include <stdio.h> #include <time.h> #include <unistd.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #define BUF_LENGTH (sizeof(struct mybuffer)) #define LETTER_NUM 32 #define SHM_MODE 0666 #define SHM_KEY IPC_PRIVATE struct mybuffer { char letter[LETTER_NUM]; }; int get_random() { struct timeval tms; gettimeofday(&tms, NULL); srand((unsigned)(getpid() + tms.tv_sec + tms.tv_usec)); return rand() % 5; } int main(int argc, char * argv[]) { int shm_id; struct mybuffer *shmptr; if ((shm_id = shmget(IPC_PRIVATE, BUF_LENGTH, SHM_MODE)) < 0) { printf("Error on shmget.\n"); exit(1); } printf("shm_id = %d\n", shm_id); if ((shmptr = shmat(shm_id, 0, 0)) == (void *)-1) { printf("Error on shmat.\n"); exit(1); } while (1) { sleep(get_random()); snprintf(shmptr->letter, LETTER_NUM, "%s%ld", "ABC", time(NULL)); } shmdt(shmptr); shmctl(shm_id, IPC_RMID, 0); printf("Main process ends.\n"); exit(0); }
/** processB.c */ #include <stdio.h> #include <time.h> #include <unistd.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #define BUF_LENGTH (sizeof(struct mybuffer)) #define LETTER_NUM 32 struct mybuffer { char letter[LETTER_NUM]; }; int get_random() { struct timeval tms; gettimeofday(&tms, NULL); srand((unsigned)(getpid() + tms.tv_sec + tms.tv_usec)); return rand() % 5; } int main(int argc, char * argv[]) { int shm_id; struct mybuffer *shmptr; if ((shmptr = shmat(atoi(argv[1]), 0, 0)) == (void *)-1) { printf("Error on shmat.\n"); exit(1); } while (1) { sleep(get_random()); printf("%s\n", shmptr->letter); } shmdt(shmptr); shmctl(shm_id, IPC_RMID, 0); printf("Main process ends.\n"); fflush(stdout); exit(0); }
相关文章推荐
- 数字反转
- 83.手势过滤和手势屏蔽
- 你的产品该如何做好?—NPS
- Android ORM框架 greenDao使用
- android项目总结
- const的用法总结
- javascript Prototype constructor的理解(转)
- USB2.0学习笔记连载(十八):keil实现寄存器的配置及相关函数讲解(二)
- iOS学习笔记10-UIView动画
- android 应用退到后台,类似最小化moveTaskToBack(),判断是否是task的根isTaskRoot()
- 礼拜五log~jBox
- Android开发小技巧之对android颜色渐变(Gradient )的改进
- 实现数组作为函数参数传递,切返回值也是数组
- 23种设计模式(java)二
- PHP中命名空间不足之详解
- 『NYIST』第九届河南省ACM竞赛队伍选拔赛[正式赛二]-最小内积(第八届北京师范大学程序设计竞赛决赛)
- linux添加网关和出接口不同网段的路由
- leetcode 53. Maximum Subarray
- 深入浅出数据仓库中SQL性能优化之Hive篇
- win7虚拟机无法上网