kovalchuk_i_v 0 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба Имеется два потока. поток 1: запускает поток 2, открывает FIFO (Read only), читает FIFO, закрывает FIFO. поток 2: открывает FIFO (Write only), пишет в FIFO, закрывает FIFO. Работа происходит в блокирующем режиме. Проблема возникает при обмене маленьким обьемом данных. В этом случае может возникнуть ситуация, когда поток1 блокируется на открытии FIFO, а поток 2 быстро выполняет всю работу и завершается, при этом поток 1 остается заблокированым на открытии. Как побороть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amw 0 23 апреля, 2009 Опубликовано 23 апреля, 2009 · Жалоба Имеется два потока. поток 1: запускает поток 2, открывает FIFO (Read only), читает FIFO, закрывает FIFO. поток 2: открывает FIFO (Write only), пишет в FIFO, закрывает FIFO. Может так: поток 1: открывает FIFO (Read only), запускает поток 2, читает FIFO, закрывает FIFO. Суть задачи понятна, но видимо тут выжны детали :) У меня такой пример не виснет (на Core 2 Duo, одноядерного под рукой нету :)) #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> #define FIFO_NAME "fifo" int fifo_size; void read_fifo() { int fd; char *buf; int result; int count; buf = malloc(fifo_size); if (buf == NULL) { fprintf(stderr, "%s(): malloc failed: %s\n", __FUNCTION__, strerror(errno)); return; } fd = open(FIFO_NAME, O_RDONLY); if (fd < 0) { fprintf(stderr, "%s(): open failed: %s\n", __FUNCTION__, strerror(errno)); free(buf); return; } count = 0; do { result = read(fd, buf, fifo_size); if (result < 0) { fprintf(stderr, "%s(): read failed: %s\n", __FUNCTION__, strerror(errno)); free(buf); close(fd); return; } if (result > 0) { count += result; } } while (count < fifo_size); free(buf); close(fd); printf("%s(): %d bytes read\n", __FUNCTION__, count); } void write_fifo() { int fd; char *buf; int result; int count; buf = malloc(fifo_size); if (buf == NULL) { fprintf(stderr, "%s(): malloc failed: %s\n", __FUNCTION__, strerror(errno)); return; } fd = open(FIFO_NAME, O_WRONLY); if (fd < 0) { fprintf(stderr, "%s(): open failed: %s\n", __FUNCTION__, strerror(errno)); free(buf); return; } count = 0; do { result = write(fd, buf, fifo_size); if (result < 0) { fprintf(stderr, "%s(): write failed: %s\n", __FUNCTION__, strerror(errno)); free(buf); close(fd); return; } if (result > 0) { count += result; } } while (count < fifo_size); free(buf); close(fd); printf("%s(): %d bytes writen\n", __FUNCTION__, count); } int main(int argc, char * argv[]) { pid_t child; switch (argc) { case 1: { fifo_size = 1; break; } case 2: { char * ok; fifo_size = strtol(argv[1], &ok, 0); if (*ok) { printf("Error in parameter\n"); return 2; } break; } default: { printf("Usage: fifotest [size]\n"); return 1; break; } } if (mkfifo(FIFO_NAME, S_IRUSR | S_IWUSR)) { perror("mkfifo failed"); return 3; } child = fork(); if (child > 0) { /* Parent */ read_fifo(); } if (child == 0) { /* Child */ write_fifo(); } if (child < 0) { perror("fork failed"); return 5; } return 0; } Прошу прощения, недоглядел. Уработался :) Вот с потоком #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <pthread.h> #define FIFO_NAME "fifo" int fifo_size; void * read_fifo(void * arg) { int fd; char *buf = (char *)arg; int result; int count; fd = open(FIFO_NAME, O_RDONLY); if (fd < 0) { fprintf(stderr, "%s(): open failed: %s\n", __FUNCTION__, strerror(errno)); return NULL; } // printf("reading...\n"); count = 0; do { result = read(fd, buf, fifo_size); if (result < 0) { fprintf(stderr, "%s(): read failed: %s\n", __FUNCTION__, strerror(errno)); close(fd); return NULL; } if (result > 0) { count += result; } } while (count < fifo_size); close(fd); printf("%s(): %d bytes read\n", __FUNCTION__, count); return NULL; } void * write_fifo(void * arg) { int fd; char *buf = (char *)arg; int result; int count; fd = open(FIFO_NAME, O_WRONLY); if (fd < 0) { fprintf(stderr, "%s(): open failed: %s\n", __FUNCTION__, strerror(errno)); return NULL; } // printf("writing...\n"); count = 0; do { result = write(fd, buf, fifo_size); if (result < 0) { fprintf(stderr, "%s(): write failed: %s\n", __FUNCTION__, strerror(errno)); close(fd); return NULL; } if (result > 0) { count += result; } } while (count < fifo_size); close(fd); printf("%s(): %d bytes writen\n", __FUNCTION__, count); return NULL; } int main(int argc, char * argv[]) { pthread_t th; pthread_attr_t attr; void *th_ret = NULL; char *rdbuf = NULL; char *wrbuf = NULL; switch (argc) { case 1: { fifo_size = 1; break; } case 2: { char * ok; fifo_size = strtol(argv[1], &ok, 0); if (*ok) { printf("Error in parameter\n"); return 2; } break; } default: { printf("Usage: fifotest [size]\n"); return 1; break; } } rdbuf = malloc(fifo_size); if (rdbuf == NULL) { perror("rdbuf = malloc() failed"); return 3; } wrbuf = malloc(fifo_size); if (wrbuf == NULL) { perror("wdbuf = malloc() failed"); return 3; } if (mkfifo(FIFO_NAME, S_IRUSR | S_IWUSR)) { perror("mkfifo failed"); return 4; } pthread_attr_init(&attr); if (pthread_create(&th, NULL, write_fifo, wrbuf) == 0) { read_fifo(rdbuf); pthread_join(th, &th_ret); } else { perror("pthread_create failed"); } free(rdbuf); free(wrbuf); return 0; } Результат тот же - нет зависаний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться