2010-11-18 3 views
9

私は取り消しポイントのglibcを/ NPTLの実装を見て、およびPOSIXとの比較、そして私が間違えてるしない限り、それは完全に間違っていてきました。使用される基本的なモデルは次のとおりPOSIXキャンセルポイントはどのように動作するはずですか?

int oldtype = LIBC_ASYNC_CANCEL(); /* switch to asynchronous cancellation mode */ 
int result = INLINE_SYSCALL(...); 
LIBC_CANCEL_RESET(oldtype); 

POSIXによれば:

関数の呼び出し中に懸濁しながら解除要求に作用するの副作用は、副作用と同じですある関数への呼び出しがシグナルによって中断され、与えられた関数が[EINTR]を返すときに、シングルスレッドプログラムで見ることができます。このような副作用は、キャンセル・クリーンアップ・ハンドラーが呼び出される前に発生します。

この通路の私の読書は、私がopenを呼び出す場合、私はそれどちらかそれはファイルを開くことができない前に(私の全体のスレッドと一緒に)取り消さ取得するには、またはが有効を返すことを期待することができるということですファイルディスクリプタまたは-1とerrnoの値を使用しますが、新しいファイルディスクリプタを作成して無効にしないでください。一方、キャンセルポイントのglibc/nptl実装は、キャンセル要求がシステムコールが返された直後で、かつLIBC_CANCEL_RESETが発生する前に発生する競合状態を考慮しているようです。

は私が狂ったアム、またはその実装は本当にこれが壊れているのですか?もしそうなら、POSIXはそのような壊れた振る舞いを許します(手動で延期しない限り、取り消しを完全に使えなくするようです)、あるいはPOSIXをちょっと無視していますか?

この動作が実際に壊れている場合は、そのような競合状態なしでそれを実装するための正しい方法は何ですか?

答えて

4

が、これは標準の次の段落で明らかにされていない:

スレッドが で中断されている場合しかし、それは待っている ための取り消しポイントとイベントが 取り消し要求の前に発生しました キャンセル要求が行われたかどうか、または キャンセル要求 が保留状態のままであり、スレッドが 通常実行を再開するかどうかは不明であるため、 は処理されません。この競合状態が完全に合法行動であることを意味し

+3

はどのようにして、このような無意味な行動で堅牢なプログラムを書くのですか?キャンセルを無効にし、キャンセルを常に無効にしておき、手動で 'pthread_trycancel'を定期的に呼び出すか、何らかの方法でアップロードするコードで' open'(リソースを割り当てることができる他のキャンセルポイント)を呼び出す必要があります。そのようなリソースを検索して解放することができます(ファイルディスクリプタの場合、すべての値を渡すことは可能ですが、多大な負荷がかからないスレッドアプリケーションでは非常に危険です)。 –

+1

MMHは、私はスレッドが(まだ解除されないことがあり、次の取り消しポイントで取り消されるべきものとして、その場合には、取り消しポイントは、OSのサポートを必要とし、おそらくRそのように壊れていることを読んで..に言いますほとんどのOS)。 – ninjalj

+0

@ ninjaj:私はcmeerwが正しいかもしれないと思います。例えば、スレッドが 'open'が返ってくるのを待っているのに、' open'がすでにその仕事を終えている場合、その実装はキャンセルを起こすか保留にしてしまう可能性があります。 –

関連する問題