Multithreading 向中间工作进程发送消息时,工作进程未完成
我用“D语言编程”来学习D语言。我编写了一个简单的程序,生成一个worker,并向它发送一个数字以接收作为字符串的平方。worker 1获取数字平方,并将其发送给worker 2(一个不同的函数),以将其转换为字符串,该字符串返回给worker 1,从而将其返回给主函数调用。我可以用一根线把整件事写下来。我写它是为了更好地了解工人。我使用Multithreading 向中间工作进程发送消息时,工作进程未完成,multithreading,concurrency,d,Multithreading,Concurrency,D,我用“D语言编程”来学习D语言。我编写了一个简单的程序,生成一个worker,并向它发送一个数字以接收作为字符串的平方。worker 1获取数字平方,并将其发送给worker 2(一个不同的函数),以将其转换为字符串,该字符串返回给worker 1,从而将其返回给主函数调用。我可以用一根线把整件事写下来。我写它是为了更好地了解工人。我使用receive让worker 1根据输入进行操作。节目如下 import std.stdio; import std.concurrency; import s
receive
让worker 1根据输入进行操作。节目如下
import std.stdio;
import std.concurrency;
import std.conv;
import core.thread;
void main() {
foreach (int num; 1..100) {
auto square_tid = spawn(&square);
square_tid.send(num);
auto square = receiveOnly!string();
writeln(square);
}
}
void square() {
static i = 0;
receive (
(int num) {
auto square = num * num;
writeln("sqaure : Comes in with " , num , " for " , ++i , " time");
auto stringWorker = spawn(&stringConverter);
stringWorker.send(thisTid, square, ownerTid);
},
(Tid tid, string str) {
writeln("comes in string");
send(tid, "hello");
});
}
void stringConverter() {
static i = 0;
auto params = receiveOnly!(Tid, int, Tid)();
auto stringified = to!string(params[1]); // Stringify the square
writeln("string : Comes in with " , params[1], " for " , ++i , " time");
params[0].send(params[2], stringified); // params[0] - square function tid, params[2] - main function tid
}
我可以接收主函数tid并直接将字符串发送回。但当我回到worker 1时,它被击中,不再继续。如何使线程接收主线程和从线程的输入。关于线程的另外几个问题:
- 如果我想在不退出的情况下将-1作为数据发送给我的工作者。我怎么做
- 在整个流程中使用一个worker可以吗?或者我可以像在foreach循环中那样使用多个worker
- 本书使用以下代码。为什么它的值>=0在代码中很明显
如果我在任何术语上有错误,请纠正我 对于这种任务,最好使用std.parallelism
import std.stdio;
import std.parallelism;
void main() {
auto squares = new long[100];
foreach(i, ref elem; parallel(squares)) {
elem = i * i;
}
writeln(squares);
}
并且将-1发送到工作线程也没有问题,它不会仅在显式请求时退出线程
以下是您尝试的修改版本:
import std.stdio;
import std.concurrency;
import std.conv;
void main() {
foreach (int num; 1..100) {
auto square_tid = spawn(&square);
square_tid.send(num);
auto square = receiveOnly!string();
writeln(square);
}
}
void square() {
static shared i = 0;
receive (
(int num) {
int square = num * num;
writeln("sqaure : Comes in with " , num , " for " , ++i , " time");
auto stringWorker = spawn(&stringConverter);
stringWorker.send(thisTid, square, ownerTid);
receive ((Tid tid, string str) { writeln("comes in string"); send(tid, "hello");});
});
}
void stringConverter() {
static shared i = 0;
auto params = receiveOnly!(Tid, int, Tid)();
auto stringified = to!string(params[1]); // Stringify the square
writeln("string : Comes in with " , params[1], " for " , ++i , " time");
params[0].send(params[2], stringified); // params[0] - square function tid, params[2] - main function tid
}
更新说明
代码中的square
函数在receive
之后结束。因此,它永远不会使用(Tid-Tid,string-str)
部分尝试下一个块。这就是为什么我把它放在receive
的第一部分
每次调用spawn
都会创建新线程。由于默认情况下D使用TLS,static
关键字在您的示例中是无用的。因为在每个新线程中,i
都是0
。这就是我使用shared
关键字的原因
更新2
以下是一个版本,它可以解释更多事情是如何运作的:
import std.stdio;
import std.concurrency;
import std.conv;
void main() {
foreach (int num; 1..100) {
auto square_tid = spawn(&square);
square_tid.send(num);
auto square = receiveOnly!string();
writeln(square);
}
}
void square() {
shared static i = 0;
bool end = false;
while(!end) receive (
(int num) {
auto square = num * num;
writeln("sqaure : Comes in with " , num , " for " , ++i , " time");
auto stringWorker = spawn(&stringConverter);
stringWorker.send(square);
},
(string str) {
writeln("comes in string");
ownerTid.send(str);
end = true;
});
}
void stringConverter() {
shared static i = 0;
auto params = receiveOnly!(int)();
auto stringified = to!string(params); // Stringify the square
writeln("string : Comes in with " , params, " for " , ++i , " time");
ownerTid.send(stringified); // params[0] - square function tid, params[2] - main function tid
}
谢谢我可以使用parallel,只是想了解线程之间的消息传递:)你能解释一下为什么用tid和int中的string包装receive调用会起作用吗。为什么要让我分享,因为它们是函数的独立静态变量。如果你想了解一些东西,那么它是提问的理想场所。我将编辑我的答案,解释为什么我要添加shared,以及为什么需要将它放在recive call中
import std.stdio;
import std.concurrency;
import std.conv;
void main() {
foreach (int num; 1..100) {
auto square_tid = spawn(&square);
square_tid.send(num);
auto square = receiveOnly!string();
writeln(square);
}
}
void square() {
shared static i = 0;
bool end = false;
while(!end) receive (
(int num) {
auto square = num * num;
writeln("sqaure : Comes in with " , num , " for " , ++i , " time");
auto stringWorker = spawn(&stringConverter);
stringWorker.send(square);
},
(string str) {
writeln("comes in string");
ownerTid.send(str);
end = true;
});
}
void stringConverter() {
shared static i = 0;
auto params = receiveOnly!(int)();
auto stringified = to!string(params); // Stringify the square
writeln("string : Comes in with " , params, " for " , ++i , " time");
ownerTid.send(stringified); // params[0] - square function tid, params[2] - main function tid
}