[英]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的回答
而且,由于编译器可以决定进行优化,因此编译器需要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.