Tôi đang cố gắng kết hợp một vài chương trình như vậy (vui lòng bỏ qua mọi phần bổ sung, đây là một công việc nặng nhọc):
pv -q -l -L 1 < input.csv | ./repeat <(nc "host" 1234)
Trường hợp nguồn của chương trình lặp lại trông như sau:
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <string>
inline std::string readline(int fd, const size_t len, const char delim = '\n')
{
std::string result;
char c = 0;
for(size_t i=0; i < len; i++)
{
const int read_result = read(fd, &c, sizeof(c));
if(read_result != sizeof(c))
break;
else
{
result += c;
if(c == delim)
break;
}
}
return result;
}
int main(int argc, char ** argv)
{
constexpr int max_events = 10;
const int fd_stdin = fileno(stdin);
if (fd_stdin < 0)
{
std::cerr << "#Failed to setup standard input" << std::endl;
return -1;
}
/* General poll setup */
int epoll_fd = epoll_create1(0);
if(epoll_fd == -1) perror("epoll_create1: ");
{
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = fd_stdin;
const int result = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_stdin, &event);
if(result == -1) std::cerr << "epoll_ctl add for fd " << fd_stdin << " failed: " << strerror(errno) << std::endl;
}
if (argc > 1)
{
for (int i = 1; i < argc; i++)
{
const char * filename = argv[i];
const int fd = open(filename, O_RDONLY);
if (fd < 0)
std::cerr << "#Error opening file " << filename << ": error #" << errno << ": " << strerror(errno) << std::endl;
else
{
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = fd;
const int result = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event);
if(result == -1) std::cerr << "epoll_ctl add for fd " << fd << "(" << filename << ") failed: " << strerror(errno) << std::endl;
else std::cerr << "Added fd " << fd << " (" << filename << ") to epoll!" << std::endl;
}
}
}
struct epoll_event events[max_events];
while(int event_count = epoll_wait(epoll_fd, events, max_events, -1))
{
for (int i = 0; i < event_count; i++)
{
const std::string line = readline(events[i].data.fd, 512);
if(line.length() > 0)
std::cout << line << std::endl;
}
}
return 0;
}
Tôi nhận thấy điều này:
- Khi tôi chỉ sử dụng đường ống để
./repeat
, mọi thứ hoạt động như dự định. - Khi tôi chỉ sử dụng thay thế quá trình, mọi thứ hoạt động như dự định.
- Khi tôi đóng gói pv bằng cách sử dụng thay thế quá trình, mọi thứ hoạt động như dự định.
- Tuy nhiên, khi tôi sử dụng cấu trúc cụ thể, tôi dường như mất dữ liệu (các ký tự riêng lẻ) từ stdin!
Tôi đã thử như sau:
- Tôi đã cố gắng vô hiệu hóa bộ đệm trên đường ống giữa
pv
và./repeat
sử dụngstdbuf -i0 -o0 -e0
trên tất cả các quy trình, nhưng điều đó dường như không hoạt động. - Tôi đã trao đổi epoll cho cuộc thăm dò, không hoạt động.
- Khi tôi nhìn vào luồng giữa
pv
và./repeat
vớitee stream.csv
, điều này có vẻ đúng. - Tôi đã từng
strace
thấy những gì đang diễn ra và tôi thấy rất nhiều lần đọc byte đơn (như mong đợi) và chúng cũng cho thấy dữ liệu đang bị mất.
Tôi tự hỏi chuyện gì đang xảy ra? Hoặc những gì tôi có thể làm để điều tra thêm?
<(...)
? Có cách nào đẹp hơn<( 0<&- ...)
không?