cppマルチスレッドプログラムは、すべてのsigwait
スレッドが生成され、プログラムが初期化された後、メイン関数の最後にLinux実装のコピーを使用します。
sigset_t mask;
struct sigaction sa;
signal(SIGPIPE, SIG_IGN);
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sa.sa_flags = SA_SIGINFO | SA_NODEFER;
sa.sa_sigaction = handler;
sigaction(SIGINT, &sa, NULL);
// Copy/paste of sigwait source code
// but keeping full siginfo (instead of just returning signo)
// and adding ETIMEDOUT as a do/while continue condition
siginfo_t si = {};
int ret = 0;
do
{
ret = sigtimedwait (&mask, &si, 0);
if(ret == -1)
{
if(errno == ETIMEDOUT)
{
printf("sigtimedwait timeout\n");
}
}
}
while (ret < 0 && (errno == EINTR || errno == ETIMEDOUT));
sigwait
実装リファレンス:
int
__sigwait (const sigset_t *set, int *sig)
{
siginfo_t si;
int ret;
do
ret = __sigtimedwait (set, &si, 0);
/* Applications do not expect sigwait to return with EINTR, and the
error code is not specified by POSIX. */
while (ret < 0 && errno == EINTR);
if (ret < 0)
return errno;
*sig = si.si_signo;
return 0;
}
sigtimedwait
参考のための声明:
int sigtimedwait(const sigset_t *restrict set,
siginfo_t *restrict info,
const struct timespec *restrict timeout);
sigtimedwait
プログラムが高負荷で実行されている場合、つまりプロセスがCPUの50%を超えて使用されている場合は、ほとんどすべての使用可能メモリがSDカード書き込み操作用にキャッシュされるようにerrno
設定します。ETIMEDOUT
この条件は常に反復可能ではありませんが、最大3分間持続する高負荷シーケンス中にランダムに1回以上発生します。通常の動作中はこれは発生しません。
私たちはarmv7lでLinux 4.14を実行しています。
sigaddset と sigaction に可能なすべてのシグナルを追加しても sigaction はhandler
呼び出されません。見ると、siginfo_t si
どんな値も設定されていません。読み値はゼロです。
Linuxのマニュアルにsigtimedwait
返品に関する情報がありません。ETIMEDOUT
この問題の原因が何であるかを知っている人はいますか?