2

私は現在、生産者/消費者問題プログラムを実装しています。1 つの親プロセスと複数の子プロセスがあります。すべてが機能していkますが、プログラムが実行しているタスクの進行状況をミリ秒ごとにプログラムに出力させる必要があります。

signal()最初は関数と関数を使用するだけでよいのではないかと考えalarm()ましたが、いくつかの予備テストから、十分ではないように思われます。いくつかのログ ファイルを確認しましたonAlarm()が、呼び出されていないようです。親も子も「忙しい」ということで、イベントを受け取れていないということでしょうか。または、忙しい場合でも、onAlarm() で呼び出しを受けることができるはずですか? これに対する唯一の回避策は、これを処理する単一の責任を持つ別のプロセスを作成することです。

これは私の「イベント」コードです:

void onAlarm() {
    signal(SIGALRM, onAlarm);
    alarm(0.01);

        fprintf(outputFile, "ALAAAAAAAAAAAAAARMMMMMMMMMMM: %d\n", numberOfBytesRead);
}

int main() {
    signal(SIGALRM, onAlarm);
    alarm(0.01);
        ...
}
4

5 に答える 5

3

あなたの主な問題はalarm()、整数の秒数がかかり、alarm(0)未解決のアラームをキャンセルするために使用されることです。

自然なフォローアップの質問は次のとおりです。

1秒未満の待機を行うにはどうすればよいですか?

承認された方法が何であるかはわかりません。一部のシステムでは、micro-sleep( usleep()) 呼び出しがありますが、これは POSIX 2008 の一部ではありません。POSIX の の直接の類似物は のusleep()ようnanosleep()です。

sigtimewait()おそらく効果を達成するために使用できる があります。(の代わりにsetitimer()andを使用できる場合があります。)getitimer()usleep()

これらすべての難しさは、あなたが同期している (シグナルが到着するのを待っている間は仕事を続けることができない) か、シグナルを送信していないことです。タイムアウトを待っている間も作業を続行できる POSIX 秒未満のアラーム メカニズムはすぐにはわかりません。

于 2010-12-12T02:22:54.530 に答える
1

これがあなたの問題かどうかはわかりませんがfprintf、シグナル ハンドラ内では安全ではありません。たとえば、シグナルが内部でfprintf生成され、予期しない動作が発生する可能性があります。またはfprintf、メモリを割り当てている可能性があり、malloc実行中にシグナルがキャッチされました。この種のことは、一見ランダムなデッドロックや激しいクラッシュを引き起こす可能性があります。

シグナル ハンドラー内で複雑な計算を行う安全な方法は、シグナル ハンドラーが既に実行中のイベント ループの状態を変更することです。または、特定の問題については、他の人が示唆しているように、これに信号を使用することを避け、より単純なスリープ コールを使用してください。

于 2010-12-12T02:47:58.070 に答える
0

タイマーで 1 秒未満の精度が必要な場合は、2 番目の posix スレッドとusleep

于 2010-12-12T02:24:57.243 に答える
0

シグナルを送信する 1 秒未満のタイマーの場合、POSIX setitimer(2) 関数を使用する必要があります。

于 2010-12-12T04:52:18.883 に答える