C语言进程共享内存实现素数判断时素数分支打印值为0的问题
问题描述
我正在学习进程与进程间内存共享的相关概念,参考示例代码改造实现了基于共享内存的素数计算功能。当前代码可正常编译,也能正确判定数值是否为素数,但我发现当输入为素数时,程序打印的数值始终为0,而非输入的待检测值,请问我在共享内存的使用上哪里存在错误?
非常感谢各位的支持与解答。
原始代码如下:
#include <stdio.h> #include <math.h> #include <unistd.h> #include <sys/wait.h> #include <sys/shm.h> int main(){ int i, j; int prime; int count = 0; int *n; int shmid; int pid; printf("Enter a number:"); scanf("%d", &prime); if(prime < 0){ printf("Not a prime number!"); } else if(prime == 0){ printf("Not a prime number!"); } else{ shmid = shmget(5, 2*sizeof(float), IPC_CREAT | 0600 ); n = shmat(shmid, 0, 0); pid = fork(); if(pid > 0){ count = 0; for(j = 2; j < prime; j++){ if(prime % j == 0){ n[0] = prime; count++; wait(NULL); } } if(count == 0){ printf("%d Is a prime number!\n", n[0]); shmdt(n); } else{ printf("%d Not a prime number!\n", n[0]); shmdt(n); } } } }
错误点说明
- 共享内存未做初始赋值:
shmget新创建的共享内存会被内核默认初始化为全0,你的代码仅在检测到非素数(找到因数)的分支中才会给n[0]写入prime值。当输入为素数时,循环不会进入因数判断分支,从未向n[0]写入待检测数值,读取时自然得到初始值0。 - 共享内存申请大小类型不匹配:你定义的指针
n是int*类型,但shmget申请空间时传入的大小是2*sizeof(float),虽然多数平台int和float长度均为4字节不会立刻触发报错,但属于类型不匹配的隐患,跨平台运行时可能出现内存越界。 - 多进程逻辑完全失效:
fork()创建子进程后,你只编写了父进程(pid>0)的执行逻辑,没有任何子进程(pid==0)的处理代码,子进程创建后会直接跳出分支退出,所有素数计算逻辑实际都在父进程中运行,共享内存完全没有发挥跨进程通信的作用。 - 共享内存资源泄漏:你仅在父进程分支调用了
shmdt()断开映射,既没有处理子进程的映射断开,也没有调用shmctl()标记删除共享内存段,程序退出后申请的共享内存会一直残存在系统中。 wait()调用位置错误:你把wait(NULL)写在了因数判断的分支内部,仅当找到第一个因数时才会等待子进程退出,素数场景下不会触发wait调用,会导致子进程成为僵尸进程。
修复方法
在shmat拿到共享内存映射地址后,第一时间将待检测的prime值写入n[0],即可解决素数场景打印0的问题;同时修正共享内存申请大小、补全子进程逻辑、调整wait位置、补充共享内存删除逻辑即可。
内容的提问来源于stack exchange,提问作者Lekost93
相关产品推荐
相关产品推荐

