モノラルで Quartz.net を使用しています。次のようなスケジューラを作成すると:
ISchedulerFactory quartzSchedulerFactory = new StdSchedulerFactory();
IScheduler quartzScheduler = quartzSchedulerFactory.GetScheduler();
Quartz.Net では、クラス SimpleThreadPool で次のメソッドが呼び出されます。
/// <summary>
/// Called by the QuartzScheduler before the <see cref="ThreadPool" /> is
/// used, in order to give the it a chance to Initialize.
/// </summary>
public virtual void Initialize()
{
if (workers != null && workers.Count > 0)
{
// already initialized...
return;
}
if (count <= 0)
{
throw new SchedulerConfigException("Thread count must be > 0");
}
// create the worker threads and start them
foreach (WorkerThread wt in CreateWorkerThreads(count))
{
wt.Start();
availWorkers.AddLast(wt);
}
}
Windows ではこれで問題なく動作しますが、CentOS では wt.Start() が呼び出されるとシステムがフリーズします。プロセスを強制終了しても、プロセスは機能しなくなり、システムを再起動するだけで強制終了できます。うまくいくこともありますが、約 5 回に 1 回はプログラムを実行します。
WorkerThread の開始時に呼び出されるコードは次のとおりです。
public override void Run()
{
bool ran = false;
bool shouldRun;
lock (this)
{
shouldRun = run;
}
while (shouldRun)
{
try
{
lock (this)
{
while (runnable == null && run)
{
Monitor.Wait(this, 500);
}
if (runnable != null)
{
ran = true;
runnable.Run();
}
}
}
catch (Exception exceptionInRunnable)
{
log.Error("Error while executing the Runnable: ", exceptionInRunnable);
}
finally
{
lock (this)
{
runnable = null;
}
// repair the thread in case the runnable mucked it up...
if (Priority != tp.ThreadPriority)
{
Priority = tp.ThreadPriority;
}
if (runOnce)
{
lock (this)
{
run = false;
}
tp.ClearFromBusyWorkersList(this);
}
else if (ran)
{
ran = false;
tp.MakeAvailable(this);
}
}
// read value of run within synchronized block to be
// sure of its value
lock (this)
{
shouldRun = run;
}
}
log.Debug("WorkerThread is shut down");
}
デッドロックの問題でしょうか?もしそうなら、なぜWindowsでは起こらないのですか?
ありがとう