无法从另一个读取一个 child 写入的共享内存
Cannot read shared memory written by one child from the other
我下面的代码创建了两个 children。一个 child 写入共享内存,另一个尝试读取它。但是,当我看到阅读后打印的输出时,它读取的是空字符串而不是 "Hello".
我能够从 parent 写入并从 child 读取。但是当我尝试从 child 写入并从另一个读取时,我做不到。
这是我的代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
void spawn_children(int num_child_processes) {
int pid=0;
int i=0;
for(i = 0; i < num_child_processes; i++) {
pid = fork();
if(pid < 0) {
printf("Error\n");
exit(1);
} else if (pid == 0) {
printf("[PID:%0d] Parent=%0d\n",(int) getpid(), (int) getppid());
if(i==0) {
// ftok to generate unique key
key_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
// shmat to attach to shared memory
char *str = (char*) shmat(shmid,(void*)0,0);
str = "Hello";
printf("Data written in memory: %s\n",str);
//detach from shared memory
shmdt(str);
}
else {
// ftok to generate unique key
key_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
// shmat to attach to shared memory
char *str = (char*) shmat(shmid,(void*)0,0);
printf("Data read from memory: %s\n",str);
//detach from shared memory
shmdt(str);
// destroy the shared memory
shmctl(shmid,IPC_RMID,NULL);
}
exit(0);
} else {
wait(NULL);
}
}
}
int main() {
printf("Main process id= %0d, Parent PID = %0d\n", (int) getpid(), (int) getppid());
spawn_children(2);
return 0;
}
我首先认为这是一个顺序问题,读取发生在写入之前,而写入仍然可能发生。直到我看到您试图通过赋值复制一个字符串。
问题是您从未真正写入共享内存,因为:
str = "Hello";
不将字符串常量 "Hello"
复制到 str
引用的内存中,而是使 str
指向字符串常量。要解决此问题,您应该使用字符串复制的方法。我喜欢snprintf
。
我想我应该包括一个例子:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
char * str = malloc(sizeof(char) * 100);
/* writes Hello into the allocated buffer */
snprintf(str, 100, "%s", "Hello");
printf("%s %p\n", str, str);
free(str);
str = NULL;
/* changes pointer to refer to literal constant */
str = "Hello";
printf("%s %p\n", str, str);
}
我下面的代码创建了两个 children。一个 child 写入共享内存,另一个尝试读取它。但是,当我看到阅读后打印的输出时,它读取的是空字符串而不是 "Hello".
我能够从 parent 写入并从 child 读取。但是当我尝试从 child 写入并从另一个读取时,我做不到。
这是我的代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
void spawn_children(int num_child_processes) {
int pid=0;
int i=0;
for(i = 0; i < num_child_processes; i++) {
pid = fork();
if(pid < 0) {
printf("Error\n");
exit(1);
} else if (pid == 0) {
printf("[PID:%0d] Parent=%0d\n",(int) getpid(), (int) getppid());
if(i==0) {
// ftok to generate unique key
key_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
// shmat to attach to shared memory
char *str = (char*) shmat(shmid,(void*)0,0);
str = "Hello";
printf("Data written in memory: %s\n",str);
//detach from shared memory
shmdt(str);
}
else {
// ftok to generate unique key
key_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
// shmat to attach to shared memory
char *str = (char*) shmat(shmid,(void*)0,0);
printf("Data read from memory: %s\n",str);
//detach from shared memory
shmdt(str);
// destroy the shared memory
shmctl(shmid,IPC_RMID,NULL);
}
exit(0);
} else {
wait(NULL);
}
}
}
int main() {
printf("Main process id= %0d, Parent PID = %0d\n", (int) getpid(), (int) getppid());
spawn_children(2);
return 0;
}
我首先认为这是一个顺序问题,读取发生在写入之前,而写入仍然可能发生。直到我看到您试图通过赋值复制一个字符串。
问题是您从未真正写入共享内存,因为:
str = "Hello";
不将字符串常量 "Hello"
复制到 str
引用的内存中,而是使 str
指向字符串常量。要解决此问题,您应该使用字符串复制的方法。我喜欢snprintf
。
我想我应该包括一个例子:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
char * str = malloc(sizeof(char) * 100);
/* writes Hello into the allocated buffer */
snprintf(str, 100, "%s", "Hello");
printf("%s %p\n", str, str);
free(str);
str = NULL;
/* changes pointer to refer to literal constant */
str = "Hello";
printf("%s %p\n", str, str);
}