Python'un GIL'i üzerinde konuşulunca bunun D'de nasıl sorun oluşturmadığını iki örnekle gösterdim. Biri std.parallelism'i diğeri de std.concurrency'yi kullanıyor.
Programlar req.query yoluyla URL parametrelerinin nasıl sorgulandıklarını da gösteriyorlar. Kullanmak için örneğin 'http://127.0.0.1:8080/work?count=5' isteği gönderiliyor.
import vibe.d;
import std.parallelism;
import std.range;
import std.math;
void pi(HttpServerRequest req, HttpServerResponse res)
{
// Example adapted from http://dlang.org/phobos/std_parallelism.html
auto param = ("terms" in req.query);
immutable n = (param && !empty(*param))
? to!size_t(*param)
: 1_000_000_000;
immutable delta = 1.0 / n;
double getTerm(size_t i) {
immutable x = (i - 0.5) * delta;
return delta / (1.0 + x * x);
}
auto terms = map!getTerm(iota(n));
auto pi = 4.0 * taskPool.reduce!"a + b"(terms);
res.writeJsonBody([ "pi" : pi ]);
}
void logarithms(HttpServerRequest req, HttpServerResponse res)
{
// This example is adapted from
// http://dlang.org/phobos/std_parallelism.html
// Find the logarithm of every number from 1 to
// 100_000_000 in parallel.
auto logs = new double[100_000_000];
// Parallel foreach works with or without an index
// variable. It can be iterate by ref if range.front
// returns by ref.
// Iterate over logs using work units of size 100.
foreach(i, ref elem; parallel(logs, 100)) {
elem = log(i + 1.0);
}
// Note how Ali is cheating by "slicing" the result to return only the
// first 1000 of the logarithms.
res.writeJsonBody([ "logs" : logs[0 .. 1000]]);
}
static this()
{
auto router = new UrlRouter;
router.get("/pi", &pi);
router.get("/log", &logarithms);
auto settings = new HttpServerSettings;
settings.port = 8080;
listenHttp(settings, router);
}
import vibe.d;
import std.array;
import std.parallelism;
import std.concurrency;
void worker(Tid owner, string work)
{
// Slowed down artifically
sleep(100.msecs);
owner.send(format("%s is ready", work));
}
void employWorkers(HttpServerRequest req, HttpServerResponse res)
{
auto param = ("count" in req.query);
size_t totalWorkers = (param && !empty(*param))
? to!size_t(*param)
: totalCPUs;
// Start the workers
foreach (i; 0 .. totalWorkers) {
spawn(&worker, thisTid, format("work %s", i));
}
// Collect the results
string[] results;
foreach (i; 0 .. totalWorkers) {
auto result = receiveOnly!string();
results ~= result;
}
res.writeJsonBody([ "results" : results ]);
}
static this()
{
auto router = new UrlRouter;
router.get("/work", &employWorkers);
auto settings = new HttpServerSettings;
settings.port = 8080;
listenHttp(settings, router);
}
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]