我有一个类库应用程序调用API。在其中我有一个名为SynchronizeMe的方法。
public class APIClass
{
object baton = new object();
static int count = 0;
public void SynchronizeMe()
{
while(true)
{
lock (baton)
{
int temp = count;
Thread.Sleep(5000);
count = temp + 1;
Console.WriteLine("Thread Id " + Thread.CurrentThread.ManagedThreadId + " Name:" + Thread.CurrentThread.Name + " incremented count to " + count);
}
Thread.Sleep(1000);
}
}
}
我有两个控制台应用程序Thread1和Thread2。他们都调用SynchronizeMe方法。 喜欢
API.APIClass apicall = new API.APIClass();
apicall.SynchronizeMe();
当我运行它时,我看到它们两个打印计数从1开始。这意味着它不同步。我理解多线程的概念有什么不对吗?或代码有问题?或者同一应用程序中的线程只能同步。如果我想以这种方式同步是什么方式?
我认为Thread1和Thread2都有不同的APIClass实例,因此无法进行同步。还有出路吗?
答案 0 :(得分:2)
如果您有两个单独的控制台应用程序,则不会在它们之间共享使用lock
关键字的锁定 - lock
是单个进程的本地。
如果要锁定进程,则需要使用named mutex
。
请参阅http://www.c-sharpcorner.com/UploadFile/1d42da/threading-with-mutex/。
要使用互斥锁进行跨进程锁定,请参阅http://mikeperetz.blogspot.co.uk/2013/12/cross-process-locking-using-named-mutex.html
您的代码看起来像:
public class APIClass
{
private const string MutexName = "FAA9569-7DFE-4D6D-874D-19123FB16CBC-8739827-[SystemSpecicString]";
private Mutex _globalMutex;
private bool _owned = false;
private int timeToWait = 1000;
object baton = new object();
static int count = 0;
public void SynchronizeMe()
{
_globalMutex = new Mutex(true, MutexName, out _owned);
while(true)
{
while (!_owned)
{
// did not get the mutex, wait for it.
_owned = _globalMutex.WaitOne(timeToWait);
}
int temp = count;
Thread.Sleep(5000);
count = temp + 1;
Console.WriteLine("Thread Id " + Thread.CurrentThread.ManagedThreadId + " Name:" + Thread.CurrentThread.Name + " incremented count to " + count);
// release the mutex
_globalMutex.ReleaseMutex();
Thread.Sleep(1000);
}
}
}
答案 1 :(得分:0)
两个进程(或者说两个应用程序域)将加载库的两个完全独立的副本。
因此,lock
不仅会锁定调用程序集的副本,而且count
变量也将作为两个单独的副本存在。
您可以与mutex进行与进程无关的同步,但仍需要找到共享该计数器的方法。这可以像保存在文件或注册表项中一样简单,也可以使用数据库。但是,如果要将其保留在内存中,则需要启动第三个进程,而不是将每个库的副本加载到现有进程中。这意味着您需要inter process communication。