C/C++ - 运行 system("process &") 然后写入它的标准输入

Posted

技术标签:

【中文标题】C/C++ - 运行 system("process &") 然后写入它的标准输入【英文标题】:C/C++ - Run system("process &") and then write to its stdin 【发布时间】:2014-03-15 23:12:28 【问题描述】:

我正在研究 Linux 和 C/C++。我用一些线程(#include pthread.h)编写了一个程序,然后用 sudo 运行它。

一个线程运行一个进程(mplayer)并通过添加“&”使其保持运行,以便system()可以快速返回。

system("mplayer -loop 0 /mnt/usb/* &");

mplayer进程正常运行,按预期播放音乐。

之后,我通过运行 pidof 获取它的进程 ID。假设它返回 2449。posix 互斥锁用于在该线程和第二个线程上写入/读取该进程 ID。

在第二个线程上,我尝试使用 /proc/2449/fd/0 管道(它称为管道还是流?)将数据写入 mplayer:

system("echo \">\" > /proc/2499/fd/0");

system() 返回 0,但 mplayer 进程没有得到任何东西。 ">" 命令应该播放下一首曲目。

stdin 流是否被其他进程继承?

2449进程下列出了几个fd,其中一个(除了0)是stdin流吗?

root@pisanlink:/proc# cd 2499
root@pisanlink:/proc/2499# cd fd
root@pisanlink:/proc/2499/fd# ls
0  1  2  3  4  5  7
root@pisanlink:/proc/2499/fd# 

我还尝试了另一种方法...我使用了具有写入权限的 popen()。我尝试使用 fprintf 发送命令,但 mplayer 似乎也没有收到任何内容。

如果需要更多代码,请告诉我。

任何提示将不胜感激。谢谢。

【问题讨论】:

man 3 popen 可能更适合您的总体目标。在echo 上使用 system() 似乎特别迂回。 使用popen,您需要在向其打印命令后将FILE 设置为行缓冲或非缓冲模式(请参阅:setvbuf)或fflush。跨度> 你可以查看 mplayer 的 -slave 选项,然后通过 popen 返回的 FILE 继续发送命令。 @ChrisStratton:是的,我不应该像使用 shell 一样编程,但我只是从这个开始。 对了,有人能告诉我为什么进程下有这么多打开的fd吗? 0 1 2 3 4 5 7 【参考方案1】:

使用popen(不是系统)打开进程。它将使用可以读取或写入(但不能同时写入)的管道创建进程。在你的情况下,你会用“w”打开它来写。从那里您可以简单地使用fwrite 将数据发送到进程的标准输入。

伪代码示例:

FILE * pFile = popen("mplayer -loop 0 /mnt/usb/*", "w");

if(pFile == NULL)
   // Handle error

// Send ">" to process' stdin
const char * psData = ">";
const size_t nDataLen = strlen(psData);
size_t nNumWritten = fwrite(psData, 1, nDataLen, pFile);

if(nNumWritten != nDataLen)
   // Handle error

...

pclose(pFile);
pFile = NULL;

【讨论】:

【参考方案2】:

我使用了 mplayer slave 选项并将输入作为 fifo 文件。它工作正常。

使用 mkfifo 创建 Linux fifo 文件:

system("mkfifo /tmp/slpiplay_fifo");

使用以下命令打开 mplayer:

system("mplayer -slave -idle -really-quiet -input file=/tmp/slpiplay_fifo /mnt/usb_slpiplay/* &");

使用 fifo 将“下一个”命令传递给 mplayer:

system("echo \"pt_step 1\" >> /tmp/slpiplay_fifo");

【讨论】:

使用命名的 unix 管道是一个很好的解决方案。但不要使用system 写入文件。只需使用FILE*f =fopen("/tmp/slpiplay_fifo","w"); fprintf(f,"pt_step 1\n"); fclose(f);。产生一个进程的成本比仅仅调用一个系统调用要贵大约 1000 倍。 感谢@MarkLakata 的提示。键入系统似乎比写入文件更快。我会解决的。

以上是关于C/C++ - 运行 system("process &") 然后写入它的标准输入的主要内容,如果未能解决你的问题,请参考以下文章

如何从没有控制台窗口的 C/C++ 执行批处理文件?

C/C++Linux下system()函数引发的错误

删除 按任意键继续

LINUX下,如何使用C/C++对EXCEL进行读写!

Linux系统上的popen()库函数

以最佳方式从 system() 命令捕获标准输出 [重复]