C/C++ - 运行 system("process &") 并向其 stdin 写入

3
我正在使用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似乎也没有收到任何东西。
如果需要更多代码,请告诉我。
任何提示都将不胜感激。谢谢。

2
man 3 popen可能更符合你的整体目标。在echo上使用system()似乎特别绕行。 - undefined
使用 popen 函数时,你需要将 FILE 设定为行缓冲模式或无缓冲模式(参见:setvbuf),或者在向其中打印命令后调用 fflush - undefined
1
你可以查阅mplayer的-slave选项,然后继续通过popen返回的文件发送命令。 - undefined
@ChrisStratton:是的,我不应该像使用Shell一样编程,但我才刚刚开始。 - undefined
@sjnarv:我会查一下的。我不知道有更简洁的方法来控制mplayer。 - undefined
显示剩余2条评论
2个回答

3
使用popen(而不是system)打开进程。它将创建一个管道,您可以从中读取或写入数据(但不能同时进行)。在您的情况下,您需要使用“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;

0
我使用了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将“next”命令传递给mplayer。
system("echo \"pt_step 1\" >> /tmp/slpiplay_fifo");

2
使用命名的Unix管道是一个好的解决方案。但是不要使用system来写入文件,只需使用FILE*f =fopen("/tmp/slpiplay_fifo","w"); fprintf(f,"pt_step 1\n"); fclose(f);。生成进程的成本比仅调用系统调用多大约1000倍。 - undefined
感谢 @MarkLakata 的建议。直接使用 system 比写入文件要快一些,我会进行修正的。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接