flockでデッドロック

manにかかれている内容そのままではあるけれども、先日ハマったので記録しておく。

flock() によって作られるロックは、 オープンファイル記述 (open file description) (open(2) 参照) と関連付けられる。 したがって、ファイルディスクリプターの複製 (fork(2) や dup(2) などにより作成される) は同じロックを参照し、 これらのファイルディスクリプターのどれを使っても このロックを変更したり解放したりできる。 また、ロックの解放は、 上記の複数のファイルディスクリプターのいずれかに対して 明示的に LOCK_UN 操作を指示した場合か、これらのファイルディスクリプターがすべて 閉じられた場合に行われる。

https://linuxjm.osdn.jp/html/LDP_man-pages/man2/flock.2.htmlより

要はflockでロックを掛けた場合、大抵の場合はcloseでファイルディスクリプターを閉じればロックも解放されるのだけれども、そうではない場合もあるということ。この場合、複数のプロセスで同じファイルに対するファイルディスクリプターを持っているので、/proc/locksでロックを掛けたままになっているプロセスとinode番号を確認したあと、lsofコマンドでどのプロセスがそのinode番号のファイルをオープンしているかチェックすれば、ファイルディスクリプターを閉じていないプロセスがわかるはず。

Linux名前付きパイプによるC – Javaプロセス間通信

C – Javaプロセス間通信をするにはJNIやソケット通信といった方法があるけれども、Linux前提なら名前付きパイプの方がリソース的によさげなので実装方法のメモ。

送信側(C)

受信側(Java)

実行用シェルスクリプト

mkfifoでパイプを作ったらそれを読み書きするだけ

Linuxで各スレッドが使用しているCPU番号の出力

マルチコアCPUを活かしたコードをデバッグしている際に、動作しているCPU番号を知りたいというケースがあったので、出力させてみた。
/proc/[pid]/statの(39)にプロセスを最後に実行したCPUの番号が格納されているのでそれを取得する。

[gist id=11335550]

procのmanpageにはscanf(3)のフォーマット指定子がついているが、必要な情報以外は*を指定して読み飛ばしているため、%*lluのように長さを指定している部分と合わせて指定すると、
warning: use of assignment suppression and length modifier together in gnu_scanf format
という警告が出る。警告を取り除くには上記コードで指定しているように”ll”を外して%*uと指定する。