KengoSawa2の技術的ななにか

IT屋さんのようなKengoSawa2がなんかそれっぽい事を書いていくblogです

QSystemSemaphoreが痒いところに手が届かなかった件

環境:Mac OS X + Qt 5.3.2

QSystemSemaphore Class | QtCore 5.3 | Documentation | Qt Project

プロセスの同時起動禁止等に活用できるQSystemSemaphoreクラスですが、
僕の使いたい用途としては、痒いところに手がとどかない悲しいクラスということがわかったので、
なんとなくポイントをメモしておきます。

まず、ざっくりと使い方です。

MyMutex = new QSystemSemaphore(任意のQStringによる排他キー,同時実行可能数,QSystemSemaphore::OpenまたはQSystemSemaphore::Create);

//排他取得。ただし、他のプロセスが先に排他取得していると無限待ちとなる

if(hErrLogMutex->acquire()){
    //排他取得中にやりたいことをここにかく!!

    //あれこれし終わったら排他解放
    hErrLogMutex->release()
}

と、こんな感じで簡単にプロセス間排他を取ることができます。
しかし、acquire()には排他取得を無限に待ってしまう欠点があります。

当然、メインスレッド上でacquire()を出すとイベントループ含め止まってしまうので、くーるくるで応答不能扱いになります(´・ω・`)

で、お馬鹿な僕は以下のように対処しました。

  • QThreadで排他取得専用のスレッドを立てて、そちらで排他取得を実行する



これでメインスレッドは動けるので一安心かと思ってましたが次なる問題が発生。

  • 排他取得要求をキャンセルしたい時、キャンセルする手段がない



QThread側からterminate()したりなんだりと色々試しましたが、ダメでした。
仕方ないのでQSystemSemaphoreの中身であるIPC systemVのシステムコールのsemget,semop,semctlを直接発行して解決しちゃいました。

やりたいことにもよると思いますが、ご参考まで。

なお、QSystemSemaphoreの内部の実装はsemopです。
Qt側でIPC_NOWAITフラグを含む非同期排他取得をサポートしてくれるとありがたいなぁと思いますが・・・・、。