Я хочу записать изменения, сделанные всеми дочерними процессами, в общую переменную с родительским процессом.
Вот проблема. Родительский процесс создает структуру, подобную этой:
struct data
{
int pid;
int n;
char c;
};
Он создает k процессов, и структура разделяется со всеми его дочерними. Переменная c
инициализируется значением 'n' и работает как флаг.
Родитель регулярно "просыпается" (из "сна") через случайное количество времени (не более 2 секунд) проверяет значение c, и если c равно 'y', то печатается значение n (вместе с соответствующим pid) и делает c снова равным 'n'.
С другой стороны, каждый ребенок Pi, 1≤ i ≤ k, регулярно "просыпается" (из "сна") через случайное количество времени (не более 2 секунд) проверяет значение c, и если c равен 'n', то присваивает некоторому случайному значению значение n вместе с идентификатором процесса для pid, печатает это значение вместе со своим собственным идентификатором процесса и делает c значением 'y'.
Если выполнение программы прекращается пользователем (нажатием Ctrl- C), родительский элемент со всеми его дочерними элементами должен завершиться, а выделенная память должна быть освобождена.
Вот код:
typedef void (*sighandler_t)(int);
int shmid;
struct data
{
int pid;
int n;
char c;
};
void releaseSHM(int signum)
{
int status;
status = shmctl(shmid, IPC_RMID, NULL);
if (status == 0)
fprintf(stderr, "Remove shared memory with id = %d.\n", shmid);
else if (status == -1)
fprintf(stderr,"Cannot remove shared memory of id = %d.\n", shmid);
else
fprintf(stderr, "shmctl() returned wrong value while removing shared memory with id = %d.\n", shmid);
status = kill(0, SIGKILL);
exit(signum);
}
int main(int argc, char *argv[])
{
int num,k=5,i, p1;
struct data *s;
sighandler_t shandler;
shandler = signal(SIGINT, releaseSHM);
shmid = shmget(IPC_PRIVATE, sizeof(struct data), IPC_CREAT | 0777);
if(shmid==-1)
{
perror("shmget() failed");
exit(1);
}
s=(struct data *)shmat(shmid, NULL, 0);
s->c='n';
for(i=0;i<k;i++)
{
p1=fork();
if(p1==0)
{
while(1)
{
//shandler = signal(SIGINT, releaseSHM);
num=(rand()%3);
sleep(num);
if(s->c=='n')
{
s->n=rand();
s->pid=getpid();
printf("Child with pid %d set value of n as %d \n",s->pid,s->n);
s->c='y';
}
sleep(num);
}
}
else
{
while(1)
{
num=(rand()%3);
sleep(num);
if(s->c=='y')
printf("Parent reads value of n as %d set by child with process id %d \n",s->n, s->pid);
s->c='n';
}
}
}
return 0;
}
Это дает вывод как:
Child with pid 13883 set value of n as 846930886
Parent reads value of n as 846930886 set by child with process id 13883
Child with pid 13883 set value of n as 1957747793
Parent reads value of n as 1957747793 set by child with process id 13883
Child with pid 13883 set value of n as 719885386
Parent reads value of n as 719885386 set by child with process id 13883
Child with pid 13883 set value of n as 596516649
Parent reads value of n as 596516649 set by child with process id 13883
Child with pid 13883 set value of n as 1350490027
Parent reads value of n as 1350490027 set by child with process id 13883
^CRemove shared memory with id = 15368197.
Killed
Очевидно, что он фиксирует изменения, сделанные только одним дочерним процессом, и не дает шанса другим дочерним процессам. Как удалить эту ошибку?
Если требуется какая-либо другая информация, оставьте комментарий ниже.