
Опытный
 
Профиль
Группа: Участник
Сообщений: 326
Регистрация: 22.1.2006
Где: Dark wood of erro r
Репутация: 3 Всего: 15
|
Всем привет. Есть проблема с синхронизацией в программе. Надо было пофиксить в ней проблемы с конкурентным доступом. Одна из проблем в ней - олновременный доступ к буферу. Я добавил 2 семафора, вроде это работает. Но происходит еще какой-то race condiotion. (Скорее всего с глобальной переменной counter). Нашел про некий тип sig_atomic_t, но че-т оне компилится с ним. | Код | #include <errno.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> #include <unistd.h> #include <semaphore.h>
#include "common.h"
static void s_child (int s); int counter; sem_t *sem_prod; sem_t *sem_consm;
int main(int argc, char *argv[]) { int i; int fd_in, *fd_out, fd_bn; char buf[256]; struct sigaction sa;
/* Allocate the file descriptor array. */ fd_out = (int*) malloc ((argc - 1) * sizeof (int)); /* The bottleneck file. */ fd_bn = open (BN_FILE, O_CREAT | O_RDWR | O_TRUNC, FILE_MODE); if (fd_bn < 0) { printf ("Error opening %s: %s\n", BN_FILE, strerror (errno)); exit (1); } sem_prod = sem_open(SEM_NAME_PROD, O_CREAT | O_EXCL, SEM_MODE, SEM_VAL_ULOCKED); if (sem_prod == SEM_FAILED) { perror("sem_open()"); exit(1); } sem_consm = sem_open(SEM_NAME_CONSM, O_CREAT | O_EXCL, SEM_MODE, SEM_VAL_LOCKED); if (sem_consm == SEM_FAILED) { perror("sem_open()"); exit(1); } if (sem_unlink(SEM_NAME_PROD) == -1 || sem_unlink(SEM_NAME_CONSM) == -1) { perror("sem_unlink()"); exit(1); } /* Child will signal when terminated. */ sa.sa_flags = 0; sa.sa_handler = s_child; sigemptyset (&sa.sa_mask); sigaction (SIGCHLD, &sa, NULL); /* Traverse the command-line args. */ for (i = 1; i < argc; i++) { fd_in = open (argv[i], O_RDONLY); if (fd_in < 0) { printf ("Error opening %s: %s\n", argv[i], strerror (errno)); exit (1); } snprintf (buf, sizeof(buf), "%s%s", argv[i], TAIL); fd_out[i-1] = open (buf, O_CREAT | O_WRONLY | O_TRUNC, FILE_MODE); if (fd_out[i-1] < 0) { printf ("Error creating %s: %s\n", buf, strerror (errno)); exit (1); } switch (fork ()) { case -1: printf ("Error in fork(): %s", strerror (errno)); break; case 0: mx_input (i, fd_bn, fd_in); default: counter++; close (fd_in); } } demx_input (fd_bn, fd_out); close (fd_bn); unlink (BN_FILE); for (i = 1; i < argc; i++) close (fd_out[i-1]); free (fd_out); return 0; }
static void s_child (int s) { counter--; }
|
| Код | #include <stdlib.h> #include <sys/types.h> #include <time.h> #include <unistd.h> #include <semaphore.h> #include <stdio.h>
#include "common.h"
void mx_input (int i, int fd_bn, int fd_in) { char byte; struct timespec ts; ts.tv_sec = 0; /* Read one byte, sleep random amount of time, loop. */ while (read (fd_in, &byte, 1) > 0) { ts.tv_nsec = 0xFFL & random (); nanosleep (&ts, NULL); sem_wait(sem_prod); lseek (fd_bn, 0, SEEK_SET); write (fd_bn, &i, sizeof (int)); write (fd_bn, &byte, sizeof (char)); if (fflush(NULL) == EOF) { perror("fflush()"); exit(1); } sem_post(sem_consm); } close (fd_bn); close (fd_in); exit (0); }
|
| Код | #include <sys/types.h> #include <unistd.h> #include <semaphore.h> #include <stdio.h> #include <stdlib.h>
#include "common.h"
void demx_input(int fd_bn, int *fd_out) { int size = sizeof (int) + sizeof (char); char buf[size]; int num; while (counter) { sem_wait(sem_consm); lseek (fd_bn, 0, SEEK_SET); read (fd_bn, buf, size); num = *((int*) buf); write (fd_out[num-1], buf + sizeof (int), sizeof (char)); if (fflush(NULL) == EOF) { perror("fflush()"); exit(1); } sem_post(sem_prod); } }
|
| Код | #ifndef _COMMON_H #define _COMMON_H
#define TAIL ".copy" #define FILE_MODE (S_IRUSR | S_IWUSR) #define BN_FILE "/tmp/bn.tmp"
#define SEM_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) #define SEM_NAME_PROD "/bneck.prod" #define SEM_NAME_CONSM "/bneck.consm" #define SEM_VAL_ULOCKED 1 #define SEM_VAL_LOCKED 0
void mx_input (int i, int fd_bn, int fd_in); void demx_input (int fd_bn, int *fd_out);
extern int counter; extern sem_t *sem_prod; extern sem_t *sem_consm;
#endif
|
|