2016-03-23 5 views
1

に何が起こる私はここにdesribedのような内部メッセージキューとしてパイプを使用したい:posix pipe as a work queuePOSIXパイプ:ブロックされた書き込み+信号

はglibcの文書によると、パイプへの書き込みがアトミックですかデータはPIPE_BUFより小さい。 https://www.gnu.org/software/libc/manual/html_node/Pipe-Atomicity.html#Pipe-Atomicity

しかし、信号が発生すると書き込みが中断することがあります。パイプがほぼ満杯であるため、writeがブロックされていると仮定します。今すぐシグナルが発生します。そのデータはパイプにアトミックに書き込まれますか?

template <typename T> 
ssize_t put(const T& data) 
{  
    static_assert(sizeof(T) < PIPE_BUF, "We use the atomic property of the pipe write. So sizeof(T) MUST be smaller than PIPE_BUF"); 

    int written; 
    const size_t id = T::value; 
    written = write(m_fds[write_fd], &id, sizeof(size_t)); 
    assert(written == sizeof(size_t)); 

    const size_t sT = sizeof(T); 
    write(m_fds[write_fd], &sT, sizeof(size_t)); 
    assert(written == sizeof(size_t)); 

    write(m_fds[write_fd], &data, sizeof(T)); // * this blocks in example 
    assert(written == sizeof(T)); 

    return sizeof(T); 
} 

答えて

1

アトミックだけ"the whole amount written in one operation is not interleaved with data from any other process."

信号の中断が若干異なっていることを意味しています。 the man page of signalによれば、パイプは「低速デバイス」です。したがって、SA_RESTARTが設定されている場合を除いて、writeオペレーションは、書き込まれたデータの数で成功を返します。したがって、writeの戻り値を常にチェックして、すべてのデータが書き込まれていることを確認することをお勧めします。また、可能な信号をマスクすることもできます。

+0

ありがとうございました! writev()が3つの項目すべてをパイプに書き込むためにこの文脈での書き込みと同じ振る舞いをするかどうか聞いてもよろしいですか?さもなければ、私はミューテックスが必要になり、アトミックなプロパティは私にとって役に立たないでしょう。 –

+0

私の2番目の質問に答える:はいそれは動作します。 http://man7.org/linux/man-pages/man2/writev.2.html "readv()とwritev()によって実行されるデータ転送は、 –

関連する問題