реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> работа с FIFO в linux
Ivan_Kov
сообщение Apr 22 2009, 08:40
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 174
Регистрация: 30-10-06
Из: г. Курск
Пользователь №: 21 787



Имеется два потока.
поток 1:
CODE

запускает поток 2,
открывает FIFO (Read only),
читает FIFO,
закрывает FIFO.


поток 2:
CODE

открывает FIFO (Write only),
пишет в FIFO,
закрывает FIFO.


Работа происходит в блокирующем режиме.
Проблема возникает при обмене маленьким обьемом данных.
В этом случае может возникнуть ситуация, когда поток1 блокируется на открытии FIFO, а поток 2 быстро выполняет всю работу и завершается, при этом поток 1 остается заблокированым на открытии.
Как побороть?
Go to the top of the page
 
+Quote Post
amw
сообщение Apr 23 2009, 18:46
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Цитата(Ivan_Kov @ Apr 22 2009, 11:40) *
Имеется два потока.
поток 1:
CODE

запускает поток 2,
открывает FIFO (Read only),
читает FIFO,
закрывает FIFO.


поток 2:
CODE

открывает FIFO (Write only),
пишет в FIFO,
закрывает FIFO.

Может так:
поток 1:
CODE

открывает FIFO (Read only),
запускает поток 2,
читает FIFO,
закрывает FIFO.


Суть задачи понятна, но видимо тут выжны детали smile.gif
У меня такой пример не виснет (на Core 2 Duo, одноядерного под рукой нету smile.gif)
CODE
#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;
}



Прошу прощения, недоглядел. Уработался smile.gif
Вот с потоком
CODE
#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;
}

Результат тот же - нет зависаний.


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 14:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01375 секунд с 7
ELECTRONIX ©2004-2016