MSDN のサンプルコードを PowerShell に書き換えてみようということで、
自分で使ってみたものから書いてみます。
まずは簡単ですが System.Threading.Mutex クラスのコンストラクタの
引数が (Boolean, String) のもの
http://msdn.microsoft.com/ja-jp/library/f55ddskf(VS.80).aspx
に出ているものが元です。
他の言語のものは public class Test とかで定義していますが、
PowerShell の場合それに相当する記述にあまり意味がなさそうな
気がするので、省略して単純に function Test で書いてみました。
中身の記述だけ参考になればということで。
# This example shows how a named mutex is used to signal between
# processes or threads.
# Run this program from two (or more) command windows. Each process
# creates a Mutex object that represents the named mutex "MyMutex".
# The named mutex is a system object whose lifetime is bounded by the
# lifetimes of the Mutex objects that represent it. The named mutex
# is created when the first process creates its local Mutex; in this
# example, the named mutex is owned by the first process. The named
# mutex is destroyed when all the Mutex objects that represent it
# have been released.
# The constructor overload shown here cannot tell the calling thread
# whether initial ownership of the named mutex was granted. Therefore,
# do not request initial ownership unless you are certain that the
# thread will create the named mutex.
function Test
{
# Create the named mutex. Only one system object named
# "MyMutex" can exist; the local Mutex object represents
# this system object, regardless of which process or thread
# caused "MyMutex" to be created.
$m = New-Object System.Threading.Mutex ($false, "MyMutex")
# Try to gain control of the named mutex. If the mutex is
# controlled by another thread, wait for it to be released.
"Waiting for the Mutex." | Write-Host
$ret = $m.WaitOne()
# Keep control of the mutex until the user presses
# ENTER.
Read-Host -Prompt ("This application owns the mutex." +`
"Press ENTER to release the mutex and exit.")
$m.ReleaseMutex()
}
. Test
Mutex クラスの説明のサンプルコードで
http://msdn.microsoft.com/ja-jp/library/system.threading.mutex(VS.80).aspx
に出ているものは Thread を使っているので PowerShell では単純に書けなくて、
(特に ThreadStart のところの書き換えとか)とりあえず断念。
自分自身が今やりたかったこともプロセス間のファイルアクセスの
排他制御だったので、とりあえず Thread は登場しないという理由もあります。(^_^;
そういえばPowerShell のファイルアクセス系のコマンドレットって
排他制御がどうなってるのかとか、読み込み系はリードオンリーでオープンされるのか、
とか明記されてないですよね?
どこかに書いてありましたっけ。。。
コメント
修正を行いました。
$m = New-Object System.Threading.Mutex $false, "MyMutex"
の $false のところに $ を忘れて false になってしまっていました。
間違えたままだとMutex のコンストラクターの第1パラメター(bool initiallyOwned)に真(true)を与えたことになってしまいます。
すると、この呼び出しでシステムミューテックスが作成されたときには初期所有権を持ってしまうことになります。
MSDNでも、このパラメターに真(true)を渡しても、所有権を得たのかどうか判別する仕組みがないので偽(false)を渡せと書いてあります。
New-Objectの時点でエラーにならないので気づいていませんでした。
ごめんなさい。
修正ついでに、パラメターが3個のコンストラクターの場合の例も書いておきます。
C# 表記で
public Mutex (
bool initiallyOwned,
string name,
out bool createdNew
)
のものです。
この場合には initiallyOwned に $true を渡して所有権を要求することに意味があり、
第3パラメターに結果が返ってきます。
新たなシステムミューテックスが作成されて所有権を取得できた場合には $true
そうでなく既存のものがつかわれるなら $false です。
このような出力パラメターを使う場合 PowerShell では [ref] を使い、
[ref]$createdNew = $false # 仮の値として $false
$m = New-Object System.Threading.Mutex $false, "MyMutex", $createdNew
と書くことになります。
これで System.Management.Automation.PSReference 型が使われて値が受け渡されます。
ばらばらと書いてすみません。
もう一度修正しました。
そもそも
$m = New-Object System.Threading.Mutex ($false, "MyMutex")
とかっこで囲んで書く方がよいのですね。
(囲まなくても動いてはいますが。)
そうすると $ を抜かした時にちゃんとエラーで教えてもらえるからミスが起こりにくいと。
この流れで式モードとコマンドモードの違いの話を
http://kawasaki-shingo-ps.blog.so-net.ne.jp/2009-03-19
の方に書きました。