访问共享进程内存时出现分段错误(核心已转储)
Segmentation fault (core dumped) when accessing shared process memory
我试图让两个子进程将两个随机整数写入共享内存,然后让父进程读取它们。
我似乎无法验证写入,因为每当我尝试访问父进程中的数组元素时都会出现分段错误。
写入后立即尝试从子进程中的内存中读取没有任何作用。
#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;
}
您没有检查来自 shmget 的有效 return 值。
if (shmid<0){printf("shmget error");exit(1);};
如果这样做,您会发现分配无效,因为 key_t 已经存在,请尝试另一个 - 或者生成您自己的唯一分配:
key_t key = 1;
或
key_t key = ftok("megasuperrandom",'a');
根据 "man ftok":
Typically, a best-effort attempt combines the given proj_id byte,
the lower 16 bits of the inode number, and the lower 8 bits of the
device number into a 32-bit result. Collisions may easily happen, for
example between files on /dev/hda1 and files on /dev/sda1.
因此,作为使用 ftok() 的替代方法,您可能希望遍历一些直到找到一个有效的方法。
此外,如果您希望 children 产生不同的随机数,您可能需要使用不同的随机函数,或者将 srand() 移动到每个 child。
此外,您可能需要查看 "man waitpid"。它不会等到进程退出,它只会等待状态发生变化——这是不可预测的。如果要确保进程已退出,则必须检查 return 状态。
我试图让两个子进程将两个随机整数写入共享内存,然后让父进程读取它们。 我似乎无法验证写入,因为每当我尝试访问父进程中的数组元素时都会出现分段错误。
写入后立即尝试从子进程中的内存中读取没有任何作用。
#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;
}
您没有检查来自 shmget 的有效 return 值。
if (shmid<0){printf("shmget error");exit(1);};
如果这样做,您会发现分配无效,因为 key_t 已经存在,请尝试另一个 - 或者生成您自己的唯一分配:
key_t key = 1;
或
key_t key = ftok("megasuperrandom",'a');
根据 "man ftok":
Typically, a best-effort attempt combines the given proj_id byte, the lower 16 bits of the inode number, and the lower 8 bits of the device number into a 32-bit result. Collisions may easily happen, for example between files on /dev/hda1 and files on /dev/sda1.
因此,作为使用 ftok() 的替代方法,您可能希望遍历一些直到找到一个有效的方法。
此外,如果您希望 children 产生不同的随机数,您可能需要使用不同的随机函数,或者将 srand() 移动到每个 child。
此外,您可能需要查看 "man waitpid"。它不会等到进程退出,它只会等待状态发生变化——这是不可预测的。如果要确保进程已退出,则必须检查 return 状态。