我试图让两个子进程将两个随机整数写入共享内存,然后让父进程读取它们。 每当尝试访问父进程中的数组元素时,我都会遇到分段错误,因此似乎无法验证写作。
尝试在写完之后立即从子进程的内存中读取内容。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(){
srand(time(NULL));
int pid2;
key_t key = 12345;
int shmid = shmget(key, 2 * sizeof(int), IPC_CREAT|IPC_EXCL|0666);
int *array = (int *)shmat(shmid, 0, 0);
int pid1 = fork();
//write first array element
if (pid1 == 0){
int n1 = rand() % 10;
printf("I'm process number 1, my pid is %d and my number is %d\n", getpid(), n1);
array[0] = n1;
return 1;
}
if (pid1 > 0){
int pid2 = fork();
if (pid2 == 0){
//write second array element
int n2 = rand() % 10;
printf("I'm process number 2, my pid is %d and my number is %d\n", getpid(), n2);
array[1] = n2;
return 1;
}
}
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
//segmentation fault happens here
printf("%d\n", array[0]);
return 0;
}
答案 0 :(得分:3)
您不是要从shmget检查有效的返回值。
if (shmid<0){printf("shmget error");exit(1);};
如果这样做,您会发现分配无效,因为该key_t已经存在,请尝试另一个-或生成您自己的唯一密钥:
key_t key = 1;
或
key_t key = ftok("megasuperrandom",'a');
根据“ man ftok”:
通常,尽力而为的尝试将给定的proj_id字节组合在一起, 索引节点编号的低16位,以及 设备号转换为32位结果。碰撞很容易发生,因为 / dev / hda1上的文件和/ dev / sda1上的文件之间的示例。
因此,您可能想遍历某些对象,直到找到一个可行的对象为止,以代替使用ftok()。
此外,如果您希望孩子们使用不同的随机数,则可能需要使用不同的随机函数,或将srand()移至每个孩子。
此外,您可能需要检查“ man waitpid”。它不会等到进程退出,而只会等待状态更改-这是不可预测的。如果要确保退出该过程,则必须检查返回状态。