Регистрация: 18.08.2014
Сообщений: 4
|
Управление процессами с помощью семафоров
Всем привет!
Задание таково: имеется родительский процесс, который создает два дочерних процесса. Родительский процесс посылает дочерним сигнал SIGUSR2, после чего дочерние процессы начинают записывать в общий файл по очереди по 3 строки, пока общее количество записанных строк не станет равно 1100.
У меня не получается записать по 3 строки. Скорее всего проблема со счетчиком строк и с управлением семафором. Подскажите, в чем проблема? Спасибо.
Код:
#include <sys/sem.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>
#define LEN 30
char str[LEN];
int flag = 1, semaforID, segmentID, *pointer;
FILE *f;
pid_t dd1, dd2;
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
} sem_arg;
void Proc0(void);
void Proc1(void);
void Proc2(void);
struct sembuf sem_unset = {0,-1,SEM_UNDO};
struct sembuf sem_set = {0,1,SEM_UNDO};
struct timeval tm;
struct shmid_ds ds;
static void handler(int signo) {
if(signo == SIGUSR1)
puts("Принят SIGUSR1 от завершившегося дочернего процесса.");
else if(signo == SIGUSR2) flag = 0;
}
int main(int argc, char *argv[]) {
key_t key;
if(signal(SIGUSR1,handler) == SIG_ERR) {
perror("Невозможно обработать SIGUSR1.");
exit(EXIT_FAILURE);
}
if(signal(SIGUSR2,handler) == SIG_ERR) {
perror("Невозможно обработать SIGUSR2.");
exit(EXIT_FAILURE);
}
if((f = fopen("kr2.txt","w+t")) == NULL) {
printf("Невозможно создать файл.");
exit(EXIT_FAILURE);
}
if((segmentID = shmget(IPC_PRIVATE,sizeof(int),0666|IPC_CREAT|IPC|EXCL)) == -1) {
perror("Невозможно выделить сегмент в памяти.");
exit(EXIT_FAILURE);
}
if((key = ftok("kr2.txt",1)) < 0) {
perror("Невозможно сгенерировать ключ key.");
exit(EXIT_FAILURE);
}
if((semaforID = semget(key,1,0666|IPC_CREAT)) < 0) {
perror("Невозможно создать семафор.");
exit(EXIT_FAILURE);
}
sem_arg.val = 1;
if(semctl(semaforID,0,SETVAL,sem_arg) == -1) {
perror("Ошибка инициализации семафора 1.");
exit(EXIT_FAILURE);
}
pointer = (int*) shmat(segmentID,NULL,0);
shmctl(segmentID,IPC_STAT,&ds);
*pointer = 1;
/*strcpy(str,"String\n");
fputs(str,f);
strcpy(str,"");
strcpy(str,"Str\n");
fputs(str,f);
strcpy(str,"");
fseek(f,0,SEEK_SET);
fgets(str,20,f);
printf(str);
strcpy(str,"");
fgets(str,20,f);
printf(str);*/
if(dd1 = fork()) {
if(dd2 = fork())
Proc0();
else Proc2();
}
else Proc1();
fclose(f);
return(0);
}
void Proc0() {
printf("parent #%d",getpid());
while(getpgid(dd1) != getpgid(dd2));
kill(-dd1,SIGUSR2);
}
void Proc1() {
int n, k;
setpgid(getpid(),getpid());
while(flag);
printf("proc1 = %d",getpid());
while(1) {
semop(semaforID,&sem_unset,1);
k = *pointer;
for(n = 0; n < 3; n++) {
if(k >= 1100) break;
gettimeofday(&tm,NULL);
sprintf(str,"%4d #%d :%d\n",k,getpid(),(int) tm.tv_usec);
fputs(str,f);
strcpy(str,"");
k++;
}
*pointer = k;
semop(semaforID,&sem_set,1);
if(k >= 1100) break;
}
}
void Proc2() {
int n, k;
while(getpgid(dd2) != dd1)
setpgid(dd2,dd1);
while(flag);
printf("proc2 = %d",getpid());
while(1) {
semop(semaforID,&sem_unset,1);
k = *pointer;
for(n = 0; n < 3; n++) {
if(k >= 1100) break;
gettimeofday(&tm,NULL);
sprintf(str,"%4d #%d :%d\n",k,getpid(),(int) tm.tv_usec);
fputs(str,f);
strcpy(str,"");
k++;
}
*pointer = k;
semop(semaforID,&sem_set,1);
if(k >= 1100) break;
}
}
|