沫颖 的学生作业:
代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 1024
#define TIMEOUT_SEC 3 // 超时时间(秒)
#define MESSAGE_PREFIX "Hello from fifo1-"
// 子线程函数:读取 FIFO 数据
void *thread_function(void *arg) {
const char *fifo_name = (const char *)arg;
int fd;
char buffer[BUFFER_SIZE];
fd_set read_fds;
int ret;
// 打开有名管道
printf("Thread %lu: 打开 FIFO %s\n", pthread_self(), fifo_name);
fd = open(fifo_name, O_RDONLY);
if (fd == -1) {
perror("open");
pthread_exit(NULL);
}
// 初始化文件描述符集合
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
// 初始化超时时间
struct timeval timeout;
timeout.tv_sec = TIMEOUT_SEC; // 秒
timeout.tv_usec = 0; // 微秒
while (1) {
// 备份文件描述符集合和超时时间
fd_set read_fds_backup = read_fds;
struct timeval timeout_backup = timeout;
// 使用 select 监听
ret = select(fd + 1, &read_fds_backup, NULL, NULL, &timeout_backup);
if (ret == -1) {
perror("select");
break;
} else if (ret == 0) {
// 超时
printf("Thread %lu: Time Out!\n", pthread_self());
} else if (ret > 0) {
if (FD_ISSET(fd, &read_fds_backup)) {
// 读取数据
ssize_t bytes_read = read(fd, buffer, BUFFER_SIZE - 1);
if (bytes_read > 0) {
buffer[bytes_read] = '\0';
printf("Thread %lu 从 FIFO %s 中读取到数据: %s\n", pthread_self(),
fifo_name, buffer);
} else if (bytes_read == 0) {
// EOF
printf("Thread %lu: FIFO %s 已关闭\n", pthread_self(), fifo_name);
break;
} else {
perror("read");
break;
}
}
}
}
close(fd);
printf("Thread %lu: FIFO %s 关闭\n", pthread_self(), fifo_name);
pthread_exit(NULL);
}
int main() {
const char *fifo1 = "fifo1";
// 创建有名管道
printf("Main: 创建 FIFO %s...\n", fifo1);
if (mkfifo(fifo1, 0666) == -1) {
perror("mkfifo");
exit(EXIT_FAILURE);
}
pthread_t thread1;
// 创建线程(先启动子线程,确保读取端先打开)
printf("Main: 创建子线程\n");
if (pthread_create(&thread1, NULL, thread_function, (void *)fifo1) != 0) {
perror("pthread_create");
unlink(fifo1); // 删除有名管道
exit(EXIT_FAILURE);
}
// 等待子线程打开 FIFO 的读取端
sleep(1);
// 打开有名管道的写入端
printf("Main: 打开 FIFO %s\n", fifo1);
int fd1 = open(fifo1, O_WRONLY);
if (fd1 == -1) {
perror("open write end");
unlink(fifo1); // 删除有名管道
exit(EXIT_FAILURE);
}
// 主线程写入数据到有名管道
int counter = 0;
while (1) {
char message1[BUFFER_SIZE];
// 拼接字符串
snprintf(message1, sizeof(message1), "%s%d", MESSAGE_PREFIX, counter++);
// 写入数据
if (write(fd1, message1, strlen(message1)) == -1) {
perror("write");
}
// 等待一段时间(确保大于超时时间)
sleep(TIMEOUT_SEC + 1); // 确保写入间隔大于超时时间
}
// 关闭写入端
printf("Main: 关闭 FIFO %s\n", fifo1);
close(fd1);
// 等待线程结束
printf("Main: 等待子线程结束\n");
pthread_join(thread1, NULL);
// 删除有名管道
printf("Main: 删除 FIFO %s...\n", fifo1);
unlink(fifo1);
printf("Main: 程序退出\n");
return 0;
}
效果
felix@felixlinux:~/Desktop/Study/CProjects/imooc-embedded/Stage05/Week12/Class12/demo_12_3$ ./a.out
Main: 创建 FIFO fifo1...
Main: 创建子线程
Thread 281473641541920: 打开 FIFO fifo1
Main: 打开 FIFO fifo1
Thread 281473641541920 从 FIFO fifo1 中读取到数据: Hello from fifo1-0
Thread 281473641541920: Time Out!
Thread 281473641541920 从 FIFO fifo1 中读取到数据: Hello from fifo1-1
Thread 281473641541920: Time Out!
Thread 281473641541920 从 FIFO fifo1 中读取到数据: Hello from fifo1-2
Thread 281473641541920: Time Out!
Thread 281473641541920 从 FIFO fifo1 中读取到数据: Hello from fifo1-3
Thread 281473641541920: Time Out!
Thread 281473641541920 从 FIFO fifo1 中读取到数据: Hello from fifo1-4
Thread 281473641541920: Time Out!
Thread 281473641541920 从 FIFO fifo1 中读取到数据: Hello from fifo1-5
^C