3

ラズベリーパイで実行する「単純な」ジュークボックスをCでプログラミングしていますが、そのパフォーマンスを最適化する最良の方法を見つけるのに苦労しています。

セットアップ方法は、すべてのグラフィックス (ncurses 経由) とデータ処理を処理する 1 つのプロセスと、mp3 再生アプリケーション (xmms2) にコマンドを送信する別のプロセスを用意し、2 つのパイプで 2 つを接続することです。 「現在のプレイリストの位置を取得」などのメッセージを送信し、「現在のプレイリストの位置: 0」で応答する単純なブリッジを形成します (ただし、それほど詳細ではありません)。

すべてのパイプはノンブロッキングに設定されていますが、これらのコマンドを送信するときにまだ多くの遅延が発生します。

これは少し抽象的な質問かもしれませんが、私はCに精通しているわけではありません. .

前もって感謝します!

メインループ:

init_xmms_bridge();

pid_t pid = fork();

while(true == true)
{
    update_xmms_bridge(pid);
    if(pid != 0)
        update_screen();
}

グラフィックス.c

void update_screen(void)
{
    /* update playlist if that has changed, 
    library display if keys has been pressed etc */

    usleep(50000); // Wait .05 seconds
    refresh(); // Refresh ncurses screen
}

xmms_bridge.c (部分)

void init_xmms_bridge(void)
{
    pipe(xmms_pipe_in);
    pipe(xmms_pipe_out);

    // Set all pipes as non-blocking
    int flags = fcntl(xmms_pipe_in[0], F_GETFL, 0);
    fcntl(xmms_pipe_in[0], F_SETFL, flags | O_NONBLOCK);

    flags = fcntl(xmms_pipe_in[1], F_GETFL, 0);
    fcntl(xmms_pipe_in[1], F_SETFL, flags | O_NONBLOCK);

    flags = fcntl(xmms_pipe_out[0], F_GETFL, 0);
    fcntl(xmms_pipe_out[0], F_SETFL, flags | O_NONBLOCK);

    flags = fcntl(xmms_pipe_out[1], F_GETFL, 0);
    fcntl(xmms_pipe_out[1], F_SETFL, flags | O_NONBLOCK);

}

// Receive data from pipes
void update_xmms_bridge(pid_t process_id)
{
    if(process_id == 0) // Child process
    {
        close(xmms_pipe_out[1]);
        bytes_read_out = read(xmms_pipe_out[0],xmms_pipe_buffer_out,sizeof(xmms_pipe_buffer_out));

        if(bytes_read_out != -1)
            xmms_receive_call(xmms_pipe_buffer_out,XMMSDirectionOut);
    }
    else
    {
        close(xmms_pipe_in[1]);
        bytes_read_in = read(xmms_pipe_in[0],xmms_pipe_buffer_in,sizeof(xmms_pipe_buffer_in));

        if(bytes_read_in != -1)
            xmms_receive_call(xmms_pipe_buffer_in,XMMSDirectionIn);
    }
}

// Send data to pipes
void bridge_call(int pipe[2],const char command,char *parameters)
{
    // Make sure it works even if parameters is null
    char call[parameters == NULL ? 3 : strlen(parameters)+3];

    /* Add separator to deal with the fact
    that multiple calls can be made before 
    the loop reads the pipe. */
    call[0] = SEPARATOR_CHARACTER;
    call[1] = command;
    call[2] = '\0';

    // Concentate string before sending through pipe
    if(parameters != NULL)
        strcat(call,parameters);

    close(pipe[0]);
    write(pipe[1],call,strlen(call));
}

void xmms_bridge_call(const char command,char *parameters)
{
    bridge_call(xmms_pipe_out,command,parameters);
}

void jukebox_bridge_call(const char command,char *parameters)
{
    bridge_call(xmms_pipe_in,command,parameters);
}
4

1 に答える 1