回答
https://stackoverflow.com/a/12507520/962890
它是如此微不足道.. args!但收到了很多好的信息。谢谢大家。
编辑
链接到 github:https ://github.com/MarkusPfundstein/stream_lame_testing
原帖
我对通过管道的 IPC 有一些疑问。我的目标是接收每个 TCP/IP 流的 MP3 数据,通过 LAME 管道将其解码为 wav,进行一些数学运算并将其存储在磁盘上(作为 wav)。我对整个事情都使用非阻塞 IO。让我有点恼火的是,tcp/ip 读取速度比管道槽跛脚快得多。当我发送 ~3 MB mp3 时,文件会在几秒钟内在客户端读取。一开始,我也可以写入跛脚进程的标准输入,然后它停止写入,它读取 mp3 的其余部分,如果完成,我可以再次写入跛脚。4096 字节大约需要 1 秒(从 lame 写入和读取)。这很慢,因为我想解码我的 wav min 128kbs。
操作系统是这台微型计算机上的 debian 2.6 内核:
https://www.olimex.com/dev/imx233-olinuxino-maxi.html
65 MB 内存 400 兆赫兹
ulimit -n | grep pipe 返回 512 x 8 ,表示 4096 可以。它是一个 32 位系统。
奇怪的是
我的进程 | 蹩脚--解码--mp3input - output.wav
去得非常快。
这是我的 fork_lame 代码(它将我的进程的粗壮连接到 lame 的标准输入,反之亦然)
static char * const k_lame_args[] = {
"--decode",
"--mp3input",
"-",
"-",
NULL
};
static int
fork_lame()
{
int outfd[2];
int infd[2];
int npid;
pipe(outfd); /* Where the parent is going to write to */
pipe(infd); /* From where parent is going to read */
npid = fork();
if (npid == 0) {
close(STDOUT_FILENO);
close(STDIN_FILENO);
dup2(outfd[0], STDIN_FILENO);
dup2(infd[1], STDOUT_FILENO);
close(outfd[0]); /* Not required for the child */
close(outfd[1]);
close(infd[0]);
close(infd[1]);
if (execv("/usr/local/bin/lame", k_lame_args) == -1) {
perror("execv");
return 1;
}
} else {
s_lame_pid = npid;
close(outfd[0]); /* These are being used by the child */
close(infd[1]);
s_lame_fds[WRITE] = outfd[1];
s_lame_fds[READ] = infd[0];
}
return 0;
}
这是读取和写入功能。请不要在 write_lame_in 中那样做。当我写到 stderr 而不是 s_lame_fds[WRITE] 时,输出几乎是立即的,所以它肯定是通过 lame 的管道。但为什么 ?
static int
read_lame_out()
{
char buffer[READ_SIZE];
memset(buffer, 0, sizeof(buffer));
int i;
int br = read(s_lame_fds[READ], buffer, sizeof(buffer) - 1);
fprintf(stderr, "read %d bytes from lame out\n", br);
return br;
}
static int
write_lame_in()
{
int bytes_written;
//bytes_written = write(2, s_data_buf, s_data_len);
bytes_written = write(s_lame_fds[WRITE], s_data_buf, s_data_len);
if (bytes_written > 0) {
//fprintf(stderr, "%d bytes written\n", bytes_written);
s_data_len -= bytes_written;
fprintf(stderr, "data_len write: %d\n", s_data_len);
memmove(s_data_buf, s_data_buf + bytes_written, s_data_len);
if (s_data_len == 0) {
fprintf(stderr, "finished\n");
}
}
return bytes_written;
}
static int
read_tcp_socket(struct connection_s *connection)
{
char buffer[READ_SIZE];
int bytes_read;
bytes_read = connection_read(connection, buffer, sizeof(buffer)-1);
if (bytes_read > 0) {
//fprintf(stderr, "read %d bytes\n", bytes_read);
if (s_data_len + bytes_read > sizeof(s_data_buf)) {
fprintf(stderr, "BUFFER OVERFLOW\n");
return -1;
} else {
memcpy(s_data_buf + s_data_len,
buffer,
bytes_read);
s_data_len += bytes_read;
}
fprintf(stderr, "data_len: %d\n", s_data_len);
}
return bytes_read;
}
选择的东西是非常基本的选择逻辑。当然,所有块都是非阻塞的。
有人知道吗?我真的很感激任何帮助;-)