【发布时间】:2014-06-09 10:22:04
【问题描述】:
我很少有线程可以调用两个或多个方法。我需要同步它们,所以我尝试使用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 and 2"); process_2.Client("1 and 2");}, {process_2.Server("2 and 5"); process_5.Client("2 and 5");}, {process_6.Server("6 and 4"); process_4.Client("6 and 4");}, {process_4.Server("4 and 7"); process_7.Client("4 and 7");}, {process_1.Server("1 and 3"); process_3.Client("1 and 3");}, {process_2.Server("2 and 3"); process_3.Client("2 and 3");}, {process_4.Server("4 and 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 and 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");}。我写的{...} 中的元素之间存在依赖关系。你能帮我解决这个问题吗?我不知道如何实现这一点。
非常感谢!
完整的程序代码:
class Pipe
{
public string message;
public Pipe()
{
message = "";
}
public Pipe(string message)
{
this.message = message;
}
public void Server(object pipeName)
{
// Create a name pipe
using (NamedPipeServerStream pipeStream = new NamedPipeServerStream(pipeName.ToString()))
{
// Wait for a connection
pipeStream.WaitForConnection();
using (StreamWriter sw = new StreamWriter(pipeStream))
{
sw.AutoFlush = true;
sw.WriteLine(message);
}
}
Console.Write("Communication between processes " + pipeName.ToString());
}
public void Client(object pipeName)
{
using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(pipeName.ToString()))
{
// The connect function will indefinately wait for the pipe to become available
// If that is not acceptable specify a maximum waiting time (in ms)
pipeStream.Connect();
using (StreamReader sr = new StreamReader(pipeStream))
{
// We read a line from the pipe and print it together with the current time
message += sr.ReadLine();
}
}
Console.WriteLine(": client received message.\n");
}
static void Main(string[] args)
{
Pipe process_1 = new Pipe("Test message from process #1.");
Pipe process_2 = new Pipe();
Pipe process_3 = new Pipe();
Pipe process_4 = new Pipe();
Pipe process_5 = new Pipe();
Pipe process_6 = new Pipe("Test message from process #6.");
Pipe process_7 = new Pipe();
TaskFactory factory = Task.Factory;
// Start tasks
Task task_1 = factory.StartNew(() => { process_1.Server("1 and 2"); 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(() => { process_2.Client("1 and 2"); 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_n的变量类型是什么?是不是你自己写的一个类,包含Server和Client这两个方法,string作为sincle输入参数,void返回值?您是否尝试过首先最小化您的问题,例如从只有 2 个线程开始,然后通过添加更多线程来增加复杂性? -
我同意@isi 的观点,我在阅读这个问题时脑子转不过来......
-
我添加了完整程序的代码。是的,你理解正确:它是我自己编写的一个类,包含 Server 和 Client 两种方法,字符串作为输入参数和 void 返回值
-
@HABJAN,对不起,我试图解释我的任务。问题是:如果我在主类中添加循环,有时客户端方法在服务器之前启动,或者两个服务器在客户端之前启动。所以在控制台我有
Communication between processes 1 and 3Communication between processes 1 and 3而不是Communication between processes 1 and 3: client received message.你能帮我同步这些任务吗?
标签: c# multithreading synchronization