有个很努力的组员提交了代码,经过多次讨论后,如下
Worker::Worker(std::string file)
Worker::DoWork(){
Controller c(config);
c.StartThread();
Info info(file_);
ImportantCall(info.Start(c.loop()));
}
这里的具体技术是, Controller负责启动一个线程,这个线程给info启动,然后通过ImportantCall把启动后的info传给库。库里的代码呼叫info可以通过这个线程来响应。可以看做是通过网络通讯的,不是直接通过堆栈的调用。DoWork后,info自动消失,线程消失,完美。
有个土人给了意见,为什么需要另一个线程?如果真需要,要在main里面启动,然后把c.loop传进Worker的构造函数。
这里面有一些调试的发现,如果不启动新的线程,而是用当前线程的loop,info.Start(current.loop()),会死锁。因为ImportantCall是阻塞的。这个很努力的组员的代码很简单,很美好,可是这个意见要求很不正常。原来的代码实现了封装,需要的线程自动启动,自动结束。意见要求却从main启动。
而且吧,我已经发现了,如果把当前线程的loop传给ImportantCall会死锁的。原来的代码无论如何不会死锁,因为内部开始新的线程,用新的loop。而意见要求调用者准备好线程,并传进loop
Worker::Worker(std::string file, Loop loop):file_(file), new_loop_(loop)
Worker::DoWork(){
Controller c(config);
c.StartThread();
Info info(file_);
ImportantCall(info.Start(new_loop_));
}
这样的话,调用者就必须知道要实现一个线程,要传进新线程的loop,这比原来糟糕了。这需要调用者学新的知识才会怎么用,而且有发生错误的可能。
--
FROM 98.42.143.*