繁体   English   中英

C#。 多线程

[英]C#. Multithreading

我有两个线程。 他们中的第一种实现了两种方法,第二种仅实现了一种。 我需要这样同步线程:从第一个线程执行第一个方法,从第二个线程执行方法,从第一个线程执行第二个方法。 我尝试使用障碍物,但无济于事:

bool complete = false;

// Start tasks
Task task_1 = factory.StartNew(() =>
{
    Console.WriteLine("1");
    Thread.MemoryBarrier();
    if (complete)
    {
        Console.WriteLine("3");
    }
});

Task task_2 = factory.StartNew(() =>
{
    //Thread.MemoryBarrier();    // Barrier 3
    Console.WriteLine("2");
    Thread.MemoryBarrier();    // Barrier 1
    complete = true;
    Thread.MemoryBarrier();
});
task_2.Wait();

我该如何解决?

非常感谢你!

感谢您的所有帖子。 我尝试使用barrier类,但结果不是我需要的。 我将尝试解释我的问题。 我很少在其中调用两个或多个方法的线程:

 Barrier barrier = new Barrier(2); // 2 = #threads participating.
            bool complete = false;
            TaskFactory factory = Task.Factory;

            // Start tasks
            Task task_1 = factory.StartNew(() =>
            {
                process_1.Server("1 and 2");
                barrier.SignalAndWait(); // Wait for task 2 to catch up.
                barrier.SignalAndWait(); // Wait for task 2 to print "2" and set complete = true.

                if (complete)
                {
                    process_1.Server("1 and 3");
                }
            });
            Task task_6 = factory.StartNew(() =>
            {
                process_6.Server("6 and 4");
                process_6.Server("6 and 3");
            });
            Task task_2 = factory.StartNew(() =>
            {
                barrier.SignalAndWait(); // Wait for task 1 to print "1".
                process_2.Client("1 and 2");
                complete = true;
                barrier.SignalAndWait(); // Wait for task 1 to read complete as true.

                process_2.Server("2 and 5");
                process_2.Server("2 and 3");
            });
            Task task_4 = factory.StartNew(() =>
            {
                process_4.Client("6 and 4");
                process_4.Server("4 and 7");
                process_4.Server("4 and 3");
            });
            Task task_5 = factory.StartNew(() =>
            {
                process_5.Client("2 and 5");
                process_5.Server("5 and 3");
            });
            Task task_7 = factory.StartNew(() =>
            {
                process_7.Client("4 and 7");
                process_7.Server("7 and 3");
            });
            Task task_3 = factory.StartNew(() =>
            {
                process_3.Client("1 and 3");
                process_3.Client("2 and 3");
                process_3.Client("4 and 3");
                process_3.Client("5 and 3");
                process_3.Client("6 and 3");
                process_3.Client("7 and 3");
            });

            task_3.Wait();

我需要确保从不同线程调用方法之间的结果,例如: process_1.Server("1 and 2"); process_2.Client("1 and 2"); 在Server之前不能调用Client方法。 所有依赖项:{process_1.Server(“ 1和2”); process_2.Client(“ 1 and 2”);},{process_2.Server(“ 2和5”); process_5.Client(“ 2 and 5”);},{process_6.Server(“ 6和4”); process_4.Client(“ 6和4”);},{process_4.Server(“ 4和7”); process_7.Client(“ 4和7”);},{process_1.Server(“ 1和3”); process_3.Client(“ 1和3”);},{process_2.Server(“ 2和3”); process_3.Client(“ 2和3”);},{process_4.Server(“ 4和3”); process_3.Client(“ 4 and 3”);},{process_5.Server(“ 5 and 3”); process_3.Client(“ 5 and 3”);},{process_6.Server(“ 6 and 3”); process_3.Client(“ 6 and 3”);},{process_7.Server(“ 7 and 3”); process_3.Client(“ 7和3”);}。

在元素{...}和{...}之间没有依赖关系。 因此可以执行{process_6.Server(“ 6 and 3”); process_3.Client(“ 6 and 3”);},{process_7.Server(“ 7 and 3”); process_3.Client(“ 7 and 3”);},反之亦然{process_7.Server(“ 7 and 3”); process_3.Client(“ 7 and 3”);},{process_6.Server(“ 6 and 3”); process_3.Client(“ 6 and 3”);}。 我写的{...}元素之间存在依赖关系。 您能帮我解决这个问题吗? 我不知道如何实现这一点。 非常感谢你!

使用一个AutoResetEvent

AutoResetEvent waitA = new AutoResetEvent(false); //task_1 uses this to signal task_2
AutoResetEvent waitB = new AutoResetEvent(false); //task_2 uses this to signal task_1

// Start tasks
Task task_1 = Task.Run(() =>
               {
                   Console.WriteLine("1");
                   waitA.Set();
                   waitB.WaitOne();
                   Console.WriteLine("3");
               });

Task task_2 = Task.Run(() =>
               {
                   waitA.WaitOne();
                   Console.WriteLine("2");
                   waitB.Set();
               });
task_2.Wait();

小提琴: https//dotnetfiddle.net/rnfWRZ

该语言将以本地顺序执行方法,利用此优势并重构您的代码

        bool complete = false;

        // Start tasks
        Task task_1 = factory.StartNew(() =>
        {
            Console.WriteLine("1");
            Console.WriteLine("2");

            if (complete)
            {
                Console.WriteLine("3");
            }

            complete = true;
        });

        task_1.Wait();

同步黑客会混淆代码的意图。 避免在可能的地方!

假设您希望线程输出“ 1、2、3”,则可以这样执行:

Barrier barrier = new Barrier(2); // 2 = #threads participating.
bool complete = false;

// Start tasks
Task task_1 = Task.Factory.StartNew(() =>
{
    Console.WriteLine("1");
    barrier.SignalAndWait(); // Wait for task 2 to catch up.
    barrier.SignalAndWait(); // Wait for task 2 to print "2" and set complete = true.
    if (complete)
    {
        Console.WriteLine("3");
    }
});

Task task_2 = Task.Factory.StartNew(() =>
{
    barrier.SignalAndWait(); // Wait for task 1 to print "1".
    Console.WriteLine("2");
    complete = true;
    barrier.SignalAndWait(); // Wait for task 1 to read complete as true.
});

task_2.Wait();

您将任务与线程混淆了,因为许多任务可以使用某个线程。 来自Jon Skeet的回答

  1. 线程是一个较低层的概念:如果您直接启动一个线程,则知道它将是一个单独的线程,而不是在线程池等上执行。
  2. 不过,任务不仅仅是对“在哪里运行某些代码”的抽象-它实际上只是“对未来结果的承诺”。

而且,由于编译器可以决定进行优化,因此编译器需要MemoryBarrier来停止指令的重新排序。

您可以执行以下操作以按顺序执行

class Program
{
    static void Main(string[] args)
    {
        var task1 = new TaskFactory().StartNew(Method1);
        var task2 = task1.ContinueWith(delegate { Method2(); });
        var task3 = task2.ContinueWith(delegate { Method1(); });

    }

    private static void Method1()
    {

    }
    private static void Method2()
    {


    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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