使用信号量在三个进程之间共享内存
Sharing memory between three processes with semaphores
进程1 fork进程2和3,每个进程向共享内存写入一个与其编号相等的字符。最后一个进程应该读取内存
输出应该看起来像 "read: 123",但我得到 "read: 1"(只有最后一个进程号)
我不知道如何在多个进程中使用共享内存,有什么帮助吗?
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <zconf.h>
#include <sys/sem.h>
#include <wait.h>
int main(){
int pid1, pid2, pid3, semid, shmid, n=3;
semid = semget(1, 1, 0);
shmid = shmget(2,1024,0666|IPC_CREAT);
char *number = (char *) shmat(shmid, (void *) 0, 0);
pid1=getpid();
pid2=fork();
pid3=fork();
if(pid3==0) {
printf("Process 3 is writing...\n");
gets(number);
}
else if(pid2==0){
wait(NULL);
printf("Process 2 is writing...\n");
gets(number);
}
else{
wait(NULL);
printf("Process 1 is writing...\n");
gets(number);
printf("read: %s\n", number);
}
}
我只是想得到一些关于多进程内存写入的建议。
这是一个固定的答案,带有经过修改和简化的程序和解释。
创建 child 进程时,parent 进程使用的大部分环境都是继承的:共享内存段是自动继承的 - 您不需要 运行 任何 shmat 、shmget 或 shmctl 例程。
要读取和写入共享内存段,child 进程需要知道相应的地址:它已经有了它,因为在您的代码中它是数字变量。
我已经在我的代码中简化了你的例子:
- 只有 2 个进程:parent 和 child
- 在进程中没有使用gets:进程只是写一个字母在
共享内存:parent写'P',child写'C';在 child 之后
退出,parent 再次读取共享内存以检查该值是否为
child 写了什么
- 我加了很多printf来显示谁是当前进程(parent或child)以及进程在做什么
- 就像在您的代码中一样,parent 和 child 之间没有同步来读取和写入共享内存:这只是一个简化的示例(但在实际程序中应该有一些同步信号量或互斥量)。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>
int main(){
pid_t pid;
int shmid;
char *addr;
shmid = shmget(2,1024,0666|IPC_CREAT);
addr = (char *) shmat(shmid, (void *) 0, 0);
printf("In parent => addr: %p \n", (void *)addr);
printf("In parent => writing *addr ... \n");
*addr = 'P';
printf("In parent => ... writing *addr: done \n");
printf("In parent => reading *addr = %c \n", *addr);
pid = fork();
if(pid == 0)
{
printf("In child => PID: %d PPID: %d\n", getpid(), getppid());
printf("In child => addr: %p \n", (void *)addr);
printf("In child => reading *addr = %c \n", *addr);
printf("In child => writing *addr ... \n");
*addr = 'C';
printf("In child => ... writing *addr: done \n");
printf("In child => reading *addr = %c \n", *addr);
printf("In child => exiting \n");
exit(EXIT_SUCCESS);
}
else if(pid > 0)
{
printf("In parent => PID: %d\n", getpid());
printf("In parent => waiting for child process to finish ...\n");
wait(NULL);
printf("In parent => child process finished.\n");
printf("In parent => reading *addr = %c \n", *addr);
}
else {
printf("In parent => unable to create child process.\n");
}
printf("In parent => exiting.\n");
return EXIT_SUCCESS;
}
输出示例:
In parent => addr: 0x7fcef5100000
In parent => writing *addr ...
In parent => ... writing *addr: done
In parent => reading *addr = P
In parent => PID: 22027
In parent => waiting for child process to finish ...
In child => PID: 22028 PPID: 22027
In child => addr: 0x7fcef5100000
In child => reading *addr = P
In child => writing *addr ...
In child => ... writing *addr: done
In child => reading *addr = C
In child => exiting
In parent => child process finished.
In parent => reading *addr = C
In parent => exiting.
进程1 fork进程2和3,每个进程向共享内存写入一个与其编号相等的字符。最后一个进程应该读取内存
输出应该看起来像 "read: 123",但我得到 "read: 1"(只有最后一个进程号)
我不知道如何在多个进程中使用共享内存,有什么帮助吗?
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <zconf.h>
#include <sys/sem.h>
#include <wait.h>
int main(){
int pid1, pid2, pid3, semid, shmid, n=3;
semid = semget(1, 1, 0);
shmid = shmget(2,1024,0666|IPC_CREAT);
char *number = (char *) shmat(shmid, (void *) 0, 0);
pid1=getpid();
pid2=fork();
pid3=fork();
if(pid3==0) {
printf("Process 3 is writing...\n");
gets(number);
}
else if(pid2==0){
wait(NULL);
printf("Process 2 is writing...\n");
gets(number);
}
else{
wait(NULL);
printf("Process 1 is writing...\n");
gets(number);
printf("read: %s\n", number);
}
}
我只是想得到一些关于多进程内存写入的建议。
这是一个固定的答案,带有经过修改和简化的程序和解释。
创建 child 进程时,parent 进程使用的大部分环境都是继承的:共享内存段是自动继承的 - 您不需要 运行 任何 shmat 、shmget 或 shmctl 例程。
要读取和写入共享内存段,child 进程需要知道相应的地址:它已经有了它,因为在您的代码中它是数字变量。
我已经在我的代码中简化了你的例子:
- 只有 2 个进程:parent 和 child
- 在进程中没有使用gets:进程只是写一个字母在 共享内存:parent写'P',child写'C';在 child 之后 退出,parent 再次读取共享内存以检查该值是否为 child 写了什么
- 我加了很多printf来显示谁是当前进程(parent或child)以及进程在做什么
- 就像在您的代码中一样,parent 和 child 之间没有同步来读取和写入共享内存:这只是一个简化的示例(但在实际程序中应该有一些同步信号量或互斥量)。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>
int main(){
pid_t pid;
int shmid;
char *addr;
shmid = shmget(2,1024,0666|IPC_CREAT);
addr = (char *) shmat(shmid, (void *) 0, 0);
printf("In parent => addr: %p \n", (void *)addr);
printf("In parent => writing *addr ... \n");
*addr = 'P';
printf("In parent => ... writing *addr: done \n");
printf("In parent => reading *addr = %c \n", *addr);
pid = fork();
if(pid == 0)
{
printf("In child => PID: %d PPID: %d\n", getpid(), getppid());
printf("In child => addr: %p \n", (void *)addr);
printf("In child => reading *addr = %c \n", *addr);
printf("In child => writing *addr ... \n");
*addr = 'C';
printf("In child => ... writing *addr: done \n");
printf("In child => reading *addr = %c \n", *addr);
printf("In child => exiting \n");
exit(EXIT_SUCCESS);
}
else if(pid > 0)
{
printf("In parent => PID: %d\n", getpid());
printf("In parent => waiting for child process to finish ...\n");
wait(NULL);
printf("In parent => child process finished.\n");
printf("In parent => reading *addr = %c \n", *addr);
}
else {
printf("In parent => unable to create child process.\n");
}
printf("In parent => exiting.\n");
return EXIT_SUCCESS;
}
输出示例:
In parent => addr: 0x7fcef5100000
In parent => writing *addr ...
In parent => ... writing *addr: done
In parent => reading *addr = P
In parent => PID: 22027
In parent => waiting for child process to finish ...
In child => PID: 22028 PPID: 22027
In child => addr: 0x7fcef5100000
In child => reading *addr = P
In child => writing *addr ...
In child => ... writing *addr: done
In child => reading *addr = C
In child => exiting
In parent => child process finished.
In parent => reading *addr = C
In parent => exiting.