Lập trình D - Đồng tiền
Concurrency đang làm cho một chương trình chạy trên nhiều luồng cùng một lúc. Một ví dụ về chương trình đồng thời là một máy chủ web phản hồi nhiều máy khách cùng một lúc. Đồng thời dễ dàng truyền thông điệp nhưng rất khó viết nếu chúng dựa trên việc chia sẻ dữ liệu.
Dữ liệu được chuyển giữa các luồng được gọi là thông báo. Thông báo có thể bao gồm bất kỳ loại nào và bất kỳ số lượng biến nào. Mỗi chuỗi đều có một id, được sử dụng để chỉ định người nhận thư. Bất kỳ luồng nào bắt đầu một luồng khác được gọi là chủ sở hữu của luồng mới.
Bắt đầu chuỗi trong D
Hàm spawn () nhận một con trỏ làm tham số và bắt đầu một luồng mới từ hàm đó. Bất kỳ hoạt động nào được thực hiện bởi chức năng đó, bao gồm cả các chức năng khác mà nó có thể gọi, sẽ được thực thi trên luồng mới. Cả chủ sở hữu và công nhân đều bắt đầu thực hiện riêng lẻ như thể chúng là các chương trình độc lập.
Thí dụ
import std.stdio;
import std.stdio;
import std.concurrency;
import core.thread;
void worker(int a) {
foreach (i; 0 .. 4) {
Thread.sleep(1);
writeln("Worker Thread ",a + i);
}
}
void main() {
foreach (i; 1 .. 4) {
Thread.sleep(2);
writeln("Main Thread ",i);
spawn(≈worker, i * 5);
}
writeln("main is done.");
}
Khi đoạn mã trên được biên dịch và thực thi, nó sẽ đọc tệp được tạo trong phần trước và tạo ra kết quả sau:
Main Thread 1
Worker Thread 5
Main Thread 2
Worker Thread 6
Worker Thread 10
Main Thread 3
main is done.
Worker Thread 7
Worker Thread 11
Worker Thread 15
Worker Thread 8
Worker Thread 12
Worker Thread 16
Worker Thread 13
Worker Thread 17
Worker Thread 18
Số nhận dạng chuỗi trong D
Biến thisTid có sẵn trên toàn cầu ở cấp mô-đun luôn là id của luồng hiện tại. Ngoài ra, bạn có thể nhận threadId khi spawn được gọi. Một ví dụ đã được biểu diễn ở dưới.
Thí dụ
import std.stdio;
import std.concurrency;
void printTid(string tag) {
writefln("%s: %s, address: %s", tag, thisTid, &thisTid);
}
void worker() {
printTid("Worker");
}
void main() {
Tid myWorker = spawn(&worker);
printTid("Owner ");
writeln(myWorker);
}
Khi đoạn mã trên được biên dịch và thực thi, nó sẽ đọc tệp được tạo trong phần trước và tạo ra kết quả sau:
Owner : Tid(std.concurrency.MessageBox), address: 10C71A59C
Worker: Tid(std.concurrency.MessageBox), address: 10C71A59C
Tid(std.concurrency.MessageBox)
Tin nhắn chuyển trong D
Hàm send () gửi tin nhắn và hàm nhậnOnly () đợi một loại tin nhắn cụ thể. Có các hàm khác được đặt tên là prioritySend (), nhận (), và getTimeout (), sẽ được giải thích ở phần sau.
Chủ sở hữu trong chương trình sau sẽ gửi cho worker của nó một thông báo kiểu int và đợi một thông báo từ worker kiểu double. Các chuỗi tiếp tục gửi thư qua lại cho đến khi chủ sở hữu gửi một số nguyên âm. Một ví dụ đã được biểu diễn ở dưới.
Thí dụ
import std.stdio;
import std.concurrency;
import core.thread;
import std.conv;
void workerFunc(Tid tid) {
int value = 0;
while (value >= 0) {
value = receiveOnly!int();
auto result = to!double(value) * 5; tid.send(result);
}
}
void main() {
Tid worker = spawn(&workerFunc,thisTid);
foreach (value; 5 .. 10) {
worker.send(value);
auto result = receiveOnly!double();
writefln("sent: %s, received: %s", value, result);
}
worker.send(-1);
}
Khi đoạn mã trên được biên dịch và thực thi, nó sẽ đọc tệp được tạo trong phần trước và tạo ra kết quả sau:
sent: 5, received: 25
sent: 6, received: 30
sent: 7, received: 35
sent: 8, received: 40
sent: 9, received: 45
Tin nhắn chuyển với Chờ trong D
Dưới đây là một ví dụ đơn giản với thông báo đi kèm với chờ đợi.
import std.stdio;
import std.concurrency;
import core.thread;
import std.conv;
void workerFunc(Tid tid) {
Thread.sleep(dur!("msecs")( 500 ),);
tid.send("hello");
}
void main() {
spawn(&workerFunc,thisTid);
writeln("Waiting for a message");
bool received = false;
while (!received) {
received = receiveTimeout(dur!("msecs")( 100 ), (string message) {
writeln("received: ", message);
});
if (!received) {
writeln("... no message yet");
}
}
}
Khi đoạn mã trên được biên dịch và thực thi, nó sẽ đọc tệp được tạo trong phần trước và tạo ra kết quả sau:
Waiting for a message
... no message yet
... no message yet
... no message yet
... no message yet
received: hello