Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从不同的应用程序调用方法时出现同步问题_C#_Multithreading_C# 4.0 - Fatal编程技术网

C# 从不同的应用程序调用方法时出现同步问题

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)

我有一个名为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方法。 像

当我运行此命令时,我看到它们都从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以前的代码正在两个控制台中打印。共享计数变量对我来说并不重要。