問題タブ [kqueue]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - Epoll、kqueue、ユーザー指定のポインター:マルチスレッド環境で安全に割り当てを解除する方法は?
Unices システムで非同期 I/O アラートに使用できる機能 (Linux の epoll、BSD システムの kqueue、Solaris の /dev/poll または I/O ポートなど) はすべて、ユーザーがポインタを指定して、ユーザーが I/O アラートを受け取りたいファイル記述子。
通常、このポインターでは、ユーザーはファイル記述子を抽象化する構造 (「ストリーム」構造など) へのポインターを指定し、ユーザーは新しいファイル記述子が開かれるたびに新しい構造を割り当てます。
例えばstruct stream { int fd; int flags; callback_t on_read_fn; /* ... */ };
さて、私の質問は次のとおりです。ユーザーがマルチスレッド環境で割り当てたこの構造を安全に解放するにはどうすればよいですか?
epoll/kqueue/etc の性質上、これについて質問します。通常、カーネルからイベントのベクトルを「ダウンロード」するスレッドがあり、I/O の準備ができているファイル記述子と、それに関連付けられたユーザー ポインターが含まれています。ファイル記述子。
ここで、2 つのスレッドがあるとします。これらのイベントをダウンロードして処理 (呼び出しstream->on_read_fn();
など) する T1 と、ユーザー コード、ユーザー イベントなどを単純に実行する T2 です。
T2 がファイル記述子を閉じたい場合は、単純に閉じてclose(stream->fd);
、T1 はその fd の I/O アラートを受信しなくなるため、stream
そこで構造体の割り当てを解除しても安全です。
しかし、T1 スレッドが、現在処理しているイベントのベクトルに同じファイル記述子を既にダウンロードしており、そのファイル記述子をまだ処理していない場合はどうでしょうか?
T1 が T2 の前にスケジュールされている場合は問題ありませんが、T2 が T1 の前にスケジュールされている場合は、ファイル記述子を閉じてstream
構造体の割り当てを解除するため、スレッド T1 は、そのファイル記述子を処理するときに、ユーザーに関連付けられたポインターを持ちます。 、既に割り当て解除された構造を指しています! もちろん、これはひどくクラッシュします。
要点は、スレッド T1 がその特定のファイル記述子の I/O アラートをダウンロードしたかどうかを T2 が知ることはなく、T2 も T1 が I/O アラートをダウンロードするかどうかを予測できないことです。
これは非常にトリッキーで、頭がくらくらします。何かご意見は?このシナリオでユーザー指定のポインターを安全に解放できるのはいつですか?
注: 私の友人は、ファイル記述子を呼び出す前に、epoll/kqueue キューからファイル記述子を削除することを提案しclose(2)
ました。これは正しく、これは私が今行っていることですが、T2 は epoll/kqueue キューからファイル記述子を削除できるため、問題は解決しませんが、そのファイルの I/O イベントは保証されません。記述子はまだカーネルから「ダウンロード」されておらず、すぐにスレッド T1 によって処理されます。
c - Kqueue udata フィールドの変更
Mac では kqueue を使用していますが、udata は変更されていません。event_data
ただし、 of call で返される配列はkevent
多少変更されています。何が原因でしょうか? void* にキャストされた文字列へのポインターを渡していますkevent
。最初の 3 文字の後に読み取ると、残りは変更されています。
ありがとう
macos - `select()`でkqueueのファイル記述子をポーリングすることは可能ですか?
でkqueueを作成するとkqueue()
、ファイル記述子が返されます。しかし、このファイル記述子は で意味のあるポーリングを行うことができないようselect()
です。からポーリング/読み取りを行う標準的なkqueue()
方法はを使用していることを理解していkevent(...)
ますが、 を使用してファイル記述子をポーリングするレガシー コードと統合しようとしていますselect()
。
ここでの目標は、このベースのポーリング メカニズムで検出できる「ユーザー イベント」を起動できるようにすることでしたselect
(イベントを後で使用して「消費」する必要がある場合でもkevent()
)。EVFILT_USER
これは、この種のことを行うために生まれたように見えましたが、簡単な実験ではselect()
、イベントが kqueue に追加 (およびトリガー) されたときに、kqueue の fd が読み取り可能であると報告されず、タイムアウト (またはブロック) するだけであることが示されています。永遠に)。(しかし、同等のkevent()
呼び出しはイベントを参照/返します。)
私は何か間違ったことをしていますか?それとも、kqueue の fd を でポーリングすることはできませんselect()
か?
macos - Kqueue を使用してファイルがごみ箱に送信されたことを検出するにはどうすればよいですか?
私は mac os x で Kqueues を使用していて、フォルダーを監視しようとしているので、EVFILT_VNODE フィルターを使用しました。ファイルが削除されるたびに通知を受け取りたいのですが、NOTE_DELETE
ファイルが削除されたときにのみ検出しますがunlink() system call
、ファイルをゴミ箱に移動するときではありません。
問題は、ファイルがゴミ箱に移動されたことをどのように検出できますか?
python - kevent 関数呼び出し時の fileno エラー
ファイルモニターを構築するために、Python 2.7 で kqueue を使用していました。
最初は、フラグに 0x4000、データに 0x1 を出力し続け、エラーが発生したことが判明しました。それから、 LaclefYoshiによって与えられた 1 つの例を見つけました。
私のコード、エラーを出しています。
彼のバージョンでは、ファイル オブジェクトを kevent 関数に直接渡します。
別のバージョンでは、kevent で fileno メソッドを呼び出します。
しかし今、私は最初のバージョンがうまく動かないのに、なぜ 3 番目のバージョンがうまくいくのか本当に混乱しています。これら2つは同じものでなければなりませんよね?
私が持っている他の質問は、Python のファイル オブジェクトとは正確には何ですか? ここでは、ident が実際には整数であることがわかりました。これは、ファイル オブジェクトではなくファイル記述子である必要があります。ここでどう動く!?
ありがとう!
macos - 単一の空の Mach ポート セットを監視している kqueue が読み取り可能であることをポーリングが示すのはなぜですか?
空の Mach ポート セットという 1 つのアイテムを監視している kqueue があります。kevent64
利用可能なイベントがないことをselect
示し、kqueue が読み取りの準備ができていないことを示します。しかしpoll
、kqueueは読み取り可能であると言います! kevent64
- ただし、準備ができていると思われるイベントを後で読み取るために呼び出す場合は、そうではないようです。
私が使用しているコードは以下のとおりです。のようなものでビルドしてから、または何でもgcc -Wall -std=c99 -o test test.c
実行できます。(待機せずに 1 を読み取ろうとした後に実際に取得されたイベントの数)、(ポーリング後に読み取りの準備ができているファイル記述子の数)、および (ポーリング後に読み取りの準備ができているファイル記述子の数)./test
からの戻り値を出力します。kevent64
select
poll
私が期待する出力は次のようなもので、kqueue が空であることを示してkevent64
いますselect
。poll
しかし、私が実際に得たのはこれであり、それを示して、あることkevent64
をselect
言いpoll
、さらに、poll
kqueueが読み取り可能であることを示した後でも、読み取るイベントがないことを示しています(これが2番目の呼び出しkevent64
の理由です) kevent64
)。
( の 1 の値revents
はPOLLIN
、おそらく、ブロックせずにデータを読み取ることができることを示します。POLLRDNORM
と をPOLLRDBAND
個別に指定した場合、結果は同じです。)
なぜ不一致なのですか?
私のテストコード: