Thread synchronization in a parallel task library (TPL)

I study TPL and doubt it. This is for training purposes only, and I hope that people will direct me in the right direction.

I want only one thread to access a variable sumat a time so that it does not overwrite.

The code I have is below.

using System;
using System.Threading.Tasks;


class ThreadTest
{
    private Object thisLock = new Object();
    static int sum = 0;
    public void RunMe()
    {
        lock (thisLock)
        {
            sum = sum + 1;
        }
    }

    static void Main()
    {
        ThreadTest b = new ThreadTest();
        Task t1 = new Task(()=>b.RunMe());
        Task t2= new Task(() => b.RunMe());
        t1.Start();
        t2.Start();
        Task.WaitAll(t1, t2);
        Console.WriteLine(sum.ToString());
        Console.ReadLine();
    }
}

Question - Am I right in this code?

Question . Can I do this without blocking because I am reading it somewhere that it should be avoided because it does not allow the task to communicate with each other. I have seen some examples with asynchronous and waiting, but I am using .Net 4.0.

thank

+4
source share
3

Am

, , , , .

  • Task t1 = new Task(()=>b.RunMe()); , , Thread API
  • Task API , Task t1,t2, , , lock shared object
  • Sum object Interlocked.Increment(ref sum), , , primitive types
  • , , API Parallel.For, Task, increment , :

    using System;
    using System.Threading.Tasks;
    
    class ThreadTest
    {    
       public static int sum;
    }
    
    static void Main()
    {
    
     Parallel.For(0, 1, i =>
    {
        // Some thread instrumentation
        Console.WriteLine("i = {0}, thread = {1}", i,
        Thread.CurrentThread.ManagedThreadId);
    
        Interlocked.Increment(ref ThreadTest.sum);
    });
    
       Console.WriteLine(ThreadTest.sum.ToString());
       Console.ReadLine();
    }
    }
    
  • Thread , , 0,1, managed thread id , ,

+2

1:

, .

, , , , .

, ThreadTest , RunMe() , .

.

2:

Interlocked.Increment():

public void RunMe()
{
    Interlocked.Increment(ref sum);
}
+1

, downvotes, :).

. - , , WinAPI , , , , , RunMe , , , 2.

Try a look at atomic operations. For your scenario, this will work very well, Interlocked.Increment (ref sum). From there, you should limit yourself to direct access to the amount, but this is not a problem, because the Increment method returns the last result.

Another option is to use SpinLock, that is, IF YOU WORK REALLY QUICKLY. NEVER INCLUDE something like Console.WriteLine or any other system operations or lengthy calculations, etc.

Here are the Inrelocked examples:

using System;
using System.Threading;
using System.Threading.Tasks;

class ThreadTest
{
    /// <summary>  DO NOT TOUCH ME DIRECTLY  </summary>
    private static int sum/* = 0 zero is default*/;
    private static int Add(int add) => Interlocked.Add(ref sum, add);
    private static int Increment() => Interlocked.Increment(ref sum);
    private static int Latest() => Interlocked.Add(ref sum, 0);
    private static void RunMe() => Increment();

    static void Main()
    {
        Task t1 = new Task(RunMe);
        Task t2 = new Task(RunMe);
        t1.Start();
        t2.Start();
        Task.WaitAll(t1, t2);
        Console.WriteLine(Latest().ToString());
        Console.ReadLine();
    }
}
+1
source

Source: https://habr.com/ru/post/1652419/


All Articles