简体   繁体   中英

Issue in synchronization of method when called from different application

I have a class Library Application Called API. Inside which I have a method called 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);
            }

        }
    }

I have two console Application Thread1 and Thread2. Both of them calling SynchronizeMe Method. Like

 API.APIClass apicall = new API.APIClass();
 apicall.SynchronizeMe();

When I run this I see Both of them printing count start from 1. That means it is not syncronized. Am I understanding the concept of multi threading something wrong? Or code has issue? Or Thread in same application can only be synchronized. If I want to synchronize this way what is the way?

I think both Thread1 and Thread2 has different Instance of APIClass so Synchronization not Possible. Is there some way out?

In the case where you have two separate console applications, locks using the lock keyword are not shared between them - lock is local to the individual process.

If you want to lock across processes you need to use a named mutex instead.

See http://www.c-sharpcorner.com/UploadFile/1d42da/threading-with-mutex/ .

For cross process locking with a mutex, see http://mikeperetz.blogspot.co.uk/2013/12/cross-process-locking-using-named-mutex.html

Your code would look something like:

    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);
        }

    }
}

Two processes (or rather two app domains) will load two totally separate copies of your library.

So not only will your lock only lock the copy of the calling assembly, your count variable will exist as two separate copies as well.

You can have process-agnostic synchronization with for example a mutex but you still need to find a way to share that counter. That can be as simple as keeping it in a file or registry entry, or you could use a database. But if you want to keep it in memory, you will need to start a third process instead of loading a copy of each library into your existing processes. That means you will need inter process communication .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM