D編程 并發(fā)

2021-09-01 10:41 更新

并發(fā)使程序在多個(gè)線程上運(yùn)行,一個(gè)示例是Web服務(wù)器同時(shí)響應(yīng)多個(gè)客戶端,并發(fā)通過消息傳遞很容易,但是它們基于數(shù)據(jù)共享則很難編寫。

啟動(dòng)線程

函數(shù)spawn()將指針作為參數(shù),并從該函數(shù)啟動(dòng)新線程,該函數(shù)執(zhí)行的任何操作,包括它可能調(diào)用的其他函數(shù),都將在新線程上執(zhí)行。

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.");  
}

編譯并執(zhí)行上述代碼后,它將讀取上一部分中創(chuàng)建的文件,并產(chǎn)生以下輸出-

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

線程標(biāo)識符

在模塊級別全局可用的 thisTid 變量始終是當(dāng)前線程的ID,當(dāng)調(diào)用spawn時(shí),您也可以接收threadId。一個(gè)如下所示。

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); 
}

編譯并執(zhí)行上述代碼后,它將讀取上一部分中創(chuàng)建的文件,并產(chǎn)生以下輸出-

Owner : Tid(std.concurrency.MessageBox), address: 10C71A59C 
Worker: Tid(std.concurrency.MessageBox), address: 10C71A59C 
Tid(std.concurrency.MessageBox)

消息傳遞

函數(shù)send()發(fā)送消息,而函數(shù)receiveOnly()等待特定類型的消息。還有其他名為prioritySend(),receive()和receiveTimeout()的函數(shù),稍后將進(jìn)行說明。

以下示例向其工作程序發(fā)送int類型的消息,并等待來自double類型的消息,線程繼續(xù)來回發(fā)送消息,直到發(fā)送一個(gè)負(fù)整數(shù)。一個(gè)如下所示。

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); 
} 

編譯并執(zhí)行上述代碼后,它將讀取上一部分中創(chuàng)建的文件,并產(chǎn)生以下輸出-

sent: 5, received: 25 
sent: 6, received: 30 
sent: 7, received: 35 
sent: 8, received: 40 
sent: 9, received: 45 

等待傳遞消息

下面顯示了一個(gè)帶有等待消息傳遞的簡單示例。

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"); 
      }
   } 
}

編譯并執(zhí)行上述代碼后,它將讀取上一部分中創(chuàng)建的文件,并產(chǎn)生以下輸出-

Waiting for a message 
... no message yet 
... no message yet 
... no message yet 
... no message yet 
received: hello 


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號