C# 从不同的应用程序调用方法时出现同步问题
我有一个名为API的类库应用程序。里面有一个叫做SynchronizeMe的方法C# 从不同的应用程序调用方法时出现同步问题,c#,multithreading,c#-4.0,C#,Multithreading,C# 4.0,我有一个名为API的类库应用程序。里面有一个叫做SynchronizeMe的方法 public class APIClass { object baton = new object(); static int count = 0; public void SynchronizeMe() { while(true) { lock (baton)
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方法。
像
当我运行此命令时,我看到它们都从1开始打印计数。这意味着它不是同步的。我理解多线程的概念有什么不对吗?还是代码有问题?或同一应用程序中的线程只能同步。如果我想以这种方式同步,那是什么方式
我认为Thread1和Thread2都有不同的APIClass实例,所以同步是不可能的。有什么办法吗?在您有两个独立的控制台应用程序的情况下,使用
lock
关键字的锁不会在它们之间共享-lock
是单个进程的本地锁
如果要跨进程锁定,则需要使用名为mutex的
看
有关使用互斥锁的跨进程锁定,请参阅
您的代码看起来像:
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);
}
}
}
如果您有两个独立的控制台应用程序,则使用lock
关键字的锁不会在它们之间共享-lock
是单个进程的本地锁
如果要跨进程锁定,则需要使用名为mutex的
看
有关使用互斥锁的跨进程锁定,请参阅
您的代码看起来像:
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);
}
}
}
两个进程(或者两个应用程序域)将加载库的两个完全独立的副本
因此,不仅锁定
只锁定调用程序集的副本,而且计数
变量也将作为两个单独的副本存在
例如,您可以使用进程不可知同步,但仍然需要找到共享该计数器的方法。这可以简单到将其保存在文件或注册表项中,也可以使用数据库。但是,如果希望将其保留在内存中,则需要启动第三个进程,而不是将每个库的副本加载到现有进程中。这意味着您将需要。两个进程(或者更确切地说是两个应用程序域)将加载库的两个完全独立的副本
因此,不仅锁定
只锁定调用程序集的副本,而且计数
变量也将作为两个单独的副本存在
例如,您可以使用进程不可知同步,但仍然需要找到共享该计数器的方法。这可以简单到将其保存在文件或注册表项中,也可以使用数据库。但是,如果希望将其保留在内存中,则需要启动第三个进程,而不是将每个库的副本加载到现有进程中。这意味着您需要。要澄清,您有两个单独运行的控制台应用程序调用库,还是一个控制台应用程序中有两个线程?@user783836两个单独运行的控制台应用程序。@TBAG请参阅我的答案。要澄清,您有两个单独运行的控制台应用程序调用库,或者在一个控制台应用程序中有两个线程?@user783836两个单独运行的控制台应用程序。@TBAG请参阅我的答案,同步将起作用,它仍然不会在进程之间使用相同的计数器变量。@nvoigt fair point和它在OP中不清楚这是目标还是只是为了理解跨进程synchronization@user783836第二个线程无法获取锁。只有thread1是初始值。第二个控制台什么也没有。@TBAG这是因为两个进程都不会产生锁。原始问题中的代码也有相同的问题。我已经更新了代码示例以生成锁。但是请注意,正如@nvoigt所指出的,没有变量(如count
)在进程之间共享。为此,您需要内存映射文件或类似文件。@user783836以前的代码正在两个控制台中打印。Share count变量对我来说并不重要。虽然同步可以工作,但进程之间仍然不会使用相同的计数器变量。@nvoigt fair point,OP不清楚这是目标还是只是为了理解跨进程synchronization@user783836第二个线程无法获取锁。只有thread1是初始值。第二个控制台什么也没有。@TBAG这是因为两个进程都不会产生锁。原始问题中的代码也有相同的问题。我已经更新了代码示例以生成锁。但是请注意,正如@nvoigt所指出的,没有变量(如count
)在进程之间共享。为此,您需要内存映射文件或类似文件。@user783836以前的代码正在两个控制台中打印。共享计数变量对我来说并不重要。