D程序中的并发

时间:2014-09-04 14:03:13

标签: multithreading concurrency d

我正在尝试编写一个简单的D程序,其中包含两个线程(main和一个在main中生成),子线程从父线程接收消息。这是我的作品:

import std.stdio;
import core.thread;
import std.concurrency;
import std.c.stdio;

extern (C) int kbhit();

void readSignal(){  
    for(;;){
        bool stop = receiveOnly!bool();
        if(!stop)
            writeln("reading signal...");
        else
            writeln("stop reading signal...");
        Thread.getThis.sleep(1.seconds);
    }   
}

int main()
{
    auto reader = spawn(&readSignal);  
    bool stop = false;

    while(true){        
        if(kbhit()){                                    
            stop = true;
        }

        option 1: reader.send(stop);        
        option 2: send(reader, stop);       
    }
}


return 0;
}

基本上我等待键盘命中,打算暂停生成的线程。 这两个选项(Andrei Alexandrescu选项1和dlang docs选项2)都不适合我。我做错了什么?

3 个答案:

答案 0 :(得分:1)

在我看来,你的主要线程非常努力,向读者发送成千上万条消息。然而,读者每秒只读一个。 “真实”消息备份在大量“虚假”消息背后。

对于这种情况,您可能最好使用shared变量,而不是使用消息。两个线程都能够安全地从中读取和写入。

答案 1 :(得分:1)

如上所述,你充斥着客户端线程。 尝试添加像这样的睡眠

Thread.sleep(dur!"msecs"(1500));

答案 2 :(得分:0)

正如duselbaer和Anders S所提到的,在您的示例中,send的数量很大,但receive的数量受sleep的限制。因此,当线程实际上应该获得true时,队列中已经有大量的false

通常,如果子线程能够比父线程发送的更快地接收,那就没问题了。这是一个从您的代码生成的工作示例。 sleep调用可以通过做一些工作来代替,但这种关系通常必须成立。

import std.stdio;
import core.thread;
import std.concurrency;
import core.stdc.stdio;

extern (C) int kbhit();

void readSignal() {
    for(int i = 0; ; i++) {
        bool stop = receiveOnly!bool();
        if(!stop)
            writeln("reading signal... ", i);
        else
        {
            writeln("stop reading signal...");
            break;
        }
        Thread.getThis.sleep(1.msecs); // this should be no more than below
    }
}

int main() {
    auto reader = spawn(&readSignal);
    bool stop = false;

    while(!stop) {
        if(kbhit()) {
            stop = true;
        }

        send(reader, stop); // option 1
        // reader.send(stop); // option 2 does the same thing as above via UFCS
        Thread.getThis.sleep(1.msecs); // this should be no less than above
    }
    return 0;
}