Multi-thread programming 3 in. NET 4: sharing data (below)

Source: Internet
Author: User

The mutex method described above is used for the mutex of different threads between processes .. NET provides a method for mutually exclusive threads between different processes. You can use named mutex to achieve mutual exclusion between processes. Named mutex is a global mutex. By giving mutex a name, it can be valid among all processes. Be sure to carefully select the mutex name to avoid conflicts with other programs.

 

Using System;

Using System. Threading;

Using System. Threading. Tasks;

Namespace TaskParallel

{

Class MainClass

{

Public static void Main (string [] args)

{

String mutexName = "Parallel. MainClass ";

Mutex globalMutex;

Try

{

GlobalMutex = Mutex. OpenExisting (mutexName );

}

Catch (WaitHandleCannotBeOpenedException)

{

GlobalMutex = new Mutex (false, mutexName );

}

Task t = new Task () =>

{

While (true)

{

Console. WriteLine ("Waiting to acquire Mutex ");

GlobalMutex. WaitOne ();

Console. WriteLine ("Acquired. Press Enter to release ");

Console. ReadLine ();

GlobalMutex. ReleaseMutex ();

Console. WriteLine ("Released ");

}

});

T. Start ();

T. Wait ();

}

}

}

First use Mutex. openExist method to determine whether the name mutex already exists. If it does not exist, an exception is thrown and the Mutex (bool, string) constructor is used to create a new mutex, if the first parameter is true, the mutex is locked initially and mutex needs to be called. release () before use. Mutex also has a constructor to avoid throwing exceptions,

 

 

 

Bool created;

Mutex globalMutex = new Mutex (false, mutexName, out created );

If the value of created is false, the current name mutex already exists. After compilation, open the program twice. You can see that the two processes obtain the mutex lock in sequence:
 

Aside from that, I have successfully configured Mono 2.10.2 and MonoDevelop 2.8 in linux, and used OpenSUSE as the release version. I have tried Ubuntu and Debian before, because I have not found the latest package of MonoDevelop, not supported. NET4, a series of problems encountered during self-compilation and installation. Unless the installation package is ready-made, it is almost a disaster. OpenSUSE is very easy to use, and it is the same as Mono and supports well. MonoDevelop cannot be compared with VS2010, but it is enough.

I use Mono to compile and run the named mutex program. The compilation is fine, but it is not the expected result. There is no mutual exclusion between processes.

I don't know if it's a Mono bug. I checked it online and didn't find it. Mutual Exclusion between processes is not used much. In addition, it is Mono, and fewer users are used. Mark it.

The following describes concurrent collections. Generally, the collection type is used to share (transmit) data. If you want to access the collection object in multiple threads at the same time, you must also consider the problem of mutual exclusion. Otherwise, an error occurs, for example:

 

Using System;

Using System. Collections. Generic;

Using System. Threading;

Using System. Threading. Tasks;

 

Namespace Parallel

{

Public class ConcurrentCollection

{

Public static void Main (string [] args)

{

Queue <int> sharedQueue = new Queue <int> ();

For (int I = 0; I <10000; I ++)

SharedQueue. Enqueue (I );

Int itemCount = 0;

Task [] tasks = new Task [10];

For (int I = 0; I <10; I ++)

{

Tasks [I] = new Task () =>

{

While (sharedQueue. Count> 0)

{

Int item = sharedQueue. Dequeue ();

Interlocked. Increment (ref itemCount );

}

});

Tasks [I]. Start ();

}

Task. WaitAll (tasks );

Console. WriteLine ("{0} items processed", itemCount );

}

}

}

 

The output result is usually greater than 1000, and sometimes exits due to exceptions. This is because the Dequeue method is not an atomic operation and may be interrupted halfway through, disrupting the internal status of the Queue.

PS. The execution results of this program under Mono are completely determined, and each time they are consistent with the preset itemCount. It seems that Mono's behavior is still different from MS's. NET.

. NET 4 provides a set of types that can be accessed concurrently. collections. concurrent. concurrentQueue is used as an example. Its Enqueue and TryDequeue methods are thread-safe. If the TryDequeue method successfully acquires an object, true is returned; otherwise, false is returned. Therefore, the above Code can be changed:

while (sharedQueue.Count > 0){       int item;       while (!sharedQueue.TryDequeue(out item)) ;                             Interlocked.Increment(ref itemCount);}

In this way, you can access it securely.

PS. I don't understand why. net designed Enqueue and Dequeue to be so asymmetrical. After checking the Mono source code, it seems that its TryDequeue never returns false, that is, it is essentially symmetric with Enqueue. I tried it and did not return false. The implementation of Microsoft is different, and a large number of false values are returned. It is strange to use a while loop. The reason for this design will be further studied next time.

 

Author: yinzixin

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.