通过一个实例来学习进程间通信之----共享内存,以及使用信号量来保护
来源:互联网 发布:mac无法登录app store 编辑:程序博客网 时间:2024/05/17 21:49
/*Link with -lrt or -pthread.*/#include #include #include #include #include #include #include /* For O_* constants */#include /* For mode constants */#include #define BUF_SIZE 1024//sem_t *g_prsem, *g_pwsem;int father_do_something(int shmid);int child_do_something(int shmid);int main(void){ int shmid; int pid; shmid = shmget(IPC_PRIVATE, BUF_SIZE, 0666|IPC_CREAT); if (shmid < 0) { perror("fail to shmget.\n"); return -1; } printf("main\n"); if ((pid = fork()) < 0) { perror("fail to fork.\n"); return -1; } else if (pid == 0) { child_do_something(shmid); } else { father_do_something(shmid); /*1.IPC_RMID命令实际上不从内核删除一个段,而是仅仅把这个段标记为删除,实际的删除 * 发生最后一个进程离开这个共享段时。 * 2.当cmd为IPC_RMID时,第三个参数应为NULL。呵呵,大部分我们都是这样做,用这个 * 函数删除共享内存。 */ if ((shmctl(shmid, IPC_RMID, NULL)) < 0)// { perror("fail to shmctl.\n"); return -1; } } return 0;}int child_do_something(int shmid){ /* sem_t *sem_open(const char *name,int oflag,mode_t mode,unsigned int value);*/ char *buf; sem_t *prsem, *pwsem; void *shmaddr; // printf("child_do_something\n"); prsem = sem_open("3rsem", O_CREAT, 0666, 0); if (prsem == SEM_FAILED) { perror("fail to sem_open rsem.\n"); return -1; } pwsem = sem_open("3wsem", O_CREAT, 0666, 1);//最后一个参数完成对信号量的初始化 if (pwsem == SEM_FAILED) { perror("fail to sem_open wsem.\n"); return -1; } // printf("child_do_something2222\n"); /*void *shmat(int shmid, const void *shmaddr, int shmflg);*/ /* shmaddr 为 NULL表示由于系统来完成映射指定地址 shmflg 为0 ,表示共享内存可读可写*/ shmaddr = shmat(shmid, NULL, 0);//映射共享内存 if (shmaddr == (void *)-1) { perror("fail to shmat.\n"); return -1; } buf = (char *)shmaddr; while (1) { // printf("child_do_something3333\n"); sem_wait(prsem); // printf("child_do_something4444\n"); printf("Input the string is:%s", buf);// 由于是用fgets 获取的输入,它末尾自带一 \n if ((strcmp(buf, "quit\n")) == 0) { printf("child release share memery.\n"); if ((shmdt(shmaddr)) < 0)//取消共享内存的映射 { perror("fail to shmdt.\n"); return -1; } sem_close(prsem); sem_close(pwsem); sem_unlink("3rsem"); sem_unlink("3wsem"); break; } else { sem_post(pwsem); } } return 0; }int father_do_something(int shmid){ int tmp; char *buf; void *shmaddr; sem_t *prsem, *pwsem; printf("father_do_something\n"); prsem = sem_open("3rsem", O_CREAT, 0666, 0); if (prsem == SEM_FAILED) { perror("fail to sem_open rsem.\n"); return -1; } pwsem = sem_open("3wsem", O_CREAT, 0666, 1); // sem_getvalue(g_pwsem, &tmp); // printf("father g_pwsem value1111 is:%d\n", tmp); if (pwsem == SEM_FAILED) { perror("fail to sem_open wsem.\n"); return -1; } // printf("father_do_something2222\n"); /* void *shmat(int shmid, const void *shmaddr, int shmflg); */ shmaddr = shmat(shmid, NULL, 0);//映射共享内存 if (shmaddr == (void *)-1) { perror("fail to shmat.\n"); return -1; } buf = (char *)shmaddr; while (1) { // printf("father_do_something3333\n"); sem_getvalue(pwsem, &tmp); printf("father pwsem value222 is:%d\n", tmp); if (sem_wait(pwsem) < 0) { printf("sem_wait\n"); perror("fail to sem_wait.\n"); break; } printf("Enter string\n"); fgets(buf, BUF_SIZE, stdin); buf[BUF_SIZE - 1] = '\0'; sem_post(prsem); if ((strcmp(buf, "quit\n")) == 0) { printf("father release share memery.\n"); if ((shmdt(shmaddr)) < 0)//取消映射 { perror("fail to shmdt.\n"); return -1; } sem_close(prsem); sem_close(pwsem); sem_unlink("3rsem"); sem_unlink("3wsem"); break; } } sleep(3); return 0; }
0 0
- 通过一个实例来学习进程间通信之----共享内存,以及使用信号量来保护
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- 共享内存多进程间通信,进程间同步使用信号量来实现
- 共享内存多进程间通信,进程间同步使用信号量来实现
- 通过共享内存和信号量实现进程间的通信
- 进程间通信 内存共享信号量实例理解
- 进程通信之共享内存与信号量
- 进程通信之信号量限制共享内存
- linux进程通信之信号量、共享内存
- 进程 A、B之间利用管道 ,共享内存,信号量来进行通信
- Fusion实例1:如何通过竞技场使用共享内存来发布一个指针?
- Linux进程间通信之共享内存+信号量
- Linux下使用信号量来进行进程间通信
- 使用信号量和共享内存实现进程间通信
- 进程间通信 "共享内存" 与 “信号量”的使用
- UNIX环境高级编程学习之第十五章进程间通信 - 系统V 共享内存使用(使用信号灯保护共享内存)
- 进程间通信--信号量+共享内存
- vim 主题(colorsheme)
- 面向对象的三大特征
- 黑马程序员——Java 基础 正则表达式(复习)
- Scala学习第七天 Scala类的属性和对象私有字段实战详解
- 机器学习实践 学习笔记4 naïve Bayes
- 通过一个实例来学习进程间通信之----共享内存,以及使用信号量来保护
- HDU-1879 继续畅通工程
- 【计算机网络】三次握手和四次挥手
- Xamarin iOS+MvvmCross TableCell add Button
- JAVA 反射练习 打印指定类名的所有信息
- js jquery版本的 金额千分位转换函数(非正则,效率极高)
- struts2--基础
- Unity3D 5.1烘培
- C++静态成员函数小结(转)