我在一个主进程和他的孩子们之间用C语言共享记忆,但我无法同步他们的动作
我有一个程序可以做到这一点:我在一个主进程和他的孩子们之间用C语言共享记忆,但我无法同步他们的动作,c,signals,semaphore,C,Signals,Semaphore,我有一个程序可以做到这一点: 主程序创建了一个共享内存块(与他未来的孩子共享),大小相当于一个名为ClientInfo的结构,其中包含2个整数和一个字符串。然后程序要求用户输入存储在变量n 主程序创建n子程序。然后子程序等待来自其父亲的SIGUSR1信号 主程序向他的所有孩子发送一个SIGUSR1信号 每个子节点从终端读取一个字符串,将其写入共享内存,并以一个单位递增两个共享整数。然后他发送一个信号给他的父亲,睡1到10秒,然后结束 每次父亲收到一个信号1,它就会打印出共享内存的内容,然后只有当
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义SHM_名称“/SHM_示例”
#定义SEM1“/示例\u SEM1”
#定义SEM2“/示例\u SEM2”
#定义名称\u最大值100
类型定义结构{
int上一个客户端的上一个\u id;/!previous\u id)=-1;
(示例_struct->id)=0;
对于(i=0;i上一个id)+;
printf(“名称为:\n的介绍”);
scanf(“%s”,名称);
memcpy(示例_struct->name、nombre、sizeof(nombre));
(示例_struct->id)+;
kill(getppid(),SIGUSR1);
sem_post(sem_write);
睡眠(1+(rand()%10));
退出(退出成功);
}
}
sigprocmask(SIG_解除阻塞、屏蔽和旧屏蔽);
kill(0,SIGUSR1);
sigprocmask(SIG_块、掩码和旧掩码);
而(1){
sigsupspend(&oldsmask);
/*if(等待(空)名称,示例\u结构->id,示例\u结构->上一个\u id);
fflush(stdout);
sigpemptyset(&mask);
sigaddset(&mask,SIGUSR1);
sigprocmask(SIG_块、掩码和旧掩码);
sem_wait(sem_read);
sem_post(sem_write);
sem_post(sem_read);}
}
您可以尝试以下方法:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdatomic.h>
#define SHM_NAME "/shm_example"
#define NAME_MAX 100
typedef struct{
char name[NAME_MAX]; //!< Name of the client.
} ClientInfo;
atomic_bool done = ATOMIC_VAR_INIT(false);
void child_handler(int dummy) {
(void)dummy;
done = true;
}
int main(void) {
int i,n,*pids;
int fd_shm;
int error;
struct sigaction act;
ClientInfo *example_struct;
printf("Introduzca un numero:\n");
scanf("%d",&n);
if(!(pids = malloc(n*sizeof(int))))
exit(EXIT_FAILURE);
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
act.sa_handler = child_handler;
if (sigaction(SIGUSR1, &act, NULL) < 0) {
perror("sigaction");
exit(EXIT_FAILURE);
}
fd_shm = shm_open(SHM_NAME,O_RDWR | O_CREAT | O_EXCL,S_IRUSR | S_IWUSR);
if(fd_shm == -1) {
fprintf (stderr, "Error creating the shared memory segment \n");
return EXIT_FAILURE;
}
error = ftruncate(fd_shm, sizeof(ClientInfo));
if(error == -1) {
fprintf (stderr, "Error resizing the shared memory segment \n");
shm_unlink(SHM_NAME);
return EXIT_FAILURE;
}
/* Map the memory segment */
example_struct = (ClientInfo *)mmap(NULL, sizeof(*example_struct), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0);
if(example_struct == MAP_FAILED) {
fprintf (stderr, "Error mapping the shared memory segment \n");
shm_unlink(SHM_NAME);
return EXIT_FAILURE;
}
for (i = 0; i < n ; i++) {
pids[i] = fork();
if (pids[i] < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pids[i] == 0) {
/* Child */
while (!done) {
/* Wait for signal */
sleep(1);
}
printf("child %d wakes up\n", getpid());
sprintf(example_struct->name, "my pid is %d", getpid());
kill(getppid(),SIGUSR1);
sleep(1 + (rand()%10));
exit(EXIT_SUCCESS);
}
}
/* only father here */
for (i = 0; i < n; i++) {
done = false;
kill(pids[i], SIGUSR1);
printf("Waiting child %d\n", pids[i]);
while (!done) {
/* Wait for signal */
sleep(1);
}
printf("Answer from %d: %s\n", pids[i], example_struct->name);
wait(NULL);
}
}
您可以尝试类似的方法:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdatomic.h>
#define SHM_NAME "/shm_example"
#define NAME_MAX 100
typedef struct{
char name[NAME_MAX]; //!< Name of the client.
} ClientInfo;
atomic_bool done = ATOMIC_VAR_INIT(false);
void child_handler(int dummy) {
(void)dummy;
done = true;
}
int main(void) {
int i,n,*pids;
int fd_shm;
int error;
struct sigaction act;
ClientInfo *example_struct;
printf("Introduzca un numero:\n");
scanf("%d",&n);
if(!(pids = malloc(n*sizeof(int))))
exit(EXIT_FAILURE);
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
act.sa_handler = child_handler;
if (sigaction(SIGUSR1, &act, NULL) < 0) {
perror("sigaction");
exit(EXIT_FAILURE);
}
fd_shm = shm_open(SHM_NAME,O_RDWR | O_CREAT | O_EXCL,S_IRUSR | S_IWUSR);
if(fd_shm == -1) {
fprintf (stderr, "Error creating the shared memory segment \n");
return EXIT_FAILURE;
}
error = ftruncate(fd_shm, sizeof(ClientInfo));
if(error == -1) {
fprintf (stderr, "Error resizing the shared memory segment \n");
shm_unlink(SHM_NAME);
return EXIT_FAILURE;
}
/* Map the memory segment */
example_struct = (ClientInfo *)mmap(NULL, sizeof(*example_struct), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0);
if(example_struct == MAP_FAILED) {
fprintf (stderr, "Error mapping the shared memory segment \n");
shm_unlink(SHM_NAME);
return EXIT_FAILURE;
}
for (i = 0; i < n ; i++) {
pids[i] = fork();
if (pids[i] < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pids[i] == 0) {
/* Child */
while (!done) {
/* Wait for signal */
sleep(1);
}
printf("child %d wakes up\n", getpid());
sprintf(example_struct->name, "my pid is %d", getpid());
kill(getppid(),SIGUSR1);
sleep(1 + (rand()%10));
exit(EXIT_SUCCESS);
}
}
/* only father here */
for (i = 0; i < n; i++) {
done = false;
kill(pids[i], SIGUSR1);
printf("Waiting child %d\n", pids[i]);
while (!done) {
/* Wait for signal */
sleep(1);
}
printf("Answer from %d: %s\n", pids[i], example_struct->name);
wait(NULL);
}
}
为什么不使用信号量进行同步?@OznOg我忘了把代码放在我的问题中(我很累),现在你可以看到信号量了为什么你使用信号量而不是信号量来“通信”?@OznOg因为任务是这样说的,它指定孩子必须发送SIGUSR1给父亲。最后为什么你有信号量,那么?为什么不使用信号量进行同步呢?@OznOg我忘了把代码放在我的问题中(我很累),现在你可以看到信号量了为什么你要用信号量而不是信号量来“通信”?@OznOg因为任务是这样说的,它规定孩子必须在最后将SIGUSR1发送给父亲,那么为什么你有信号量呢?