Цитата(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.
Суть задачи понятна, но видимо тут выжны детали

У меня такой пример не виснет (на Core 2 Duo, одноядерного под рукой нету

)
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;
}
Прошу прощения, недоглядел. Уработался

Вот с потоком
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;
}
Результат тот же - нет зависаний.