c ++线程等待用户IO('getchar()')在主进程中挂起'Py_Initialize()'

Posted

技术标签:

【中文标题】c ++线程等待用户IO(\'getchar()\')在主进程中挂起\'Py_Initialize()\'【英文标题】:c++ thread waiting for user IO ('getchar()') hangs 'Py_Initialize()' in main processc ++线程等待用户IO('getchar()')在主进程中挂起'Py_Initialize()' 【发布时间】:2012-12-22 20:31:01 【问题描述】:

我刚刚偶然发现了一个非常奇怪的问题。在我的代码中,我启动了一个线程来等待用户输入——以防用户想要中断主进程。在该线程运行之后,我尝试使用 python 进行一些计算。线程使用getchar() 查找用户输入——如果输入是返回,则设置一个布尔标志以使主进程停止执行其正在执行的操作。主进程每隔一段时间检查一次这个标志,如果它被设置,它就会采取适当的行动。

示意图:

bool volatile stopper = false;
thread stopThread(interrupt, &stopper);
while( !stopper ) 
    /* ... stuff ... */
    Py_Initialize();                            // this doesn't return unless 'interrupt()' completes.
    /* ... do things with python object ... */
 

中断方法看起来像,

void interrupt(bool *st) 
    char ch;   
    while( ch != '\n' ) 
        ch = getchar();
    
    *st = true;

如果我用sleep(10) 替换getchar() while 循环,Py_Initialize() 返回正常,一切正常。为什么IO请求阻塞Py_Initialize()

谢谢!

【问题讨论】:

可能不相关,但理论上你需要用bool volatile stopper = false;声明“stopper”变量。否则C++编译器有权认为while(!stopper) 循环是一个无限循环,如果循环中没有代码可以改变stopper的值(即如果它只能从另一个线程并行改变)。 @MatsPetersson,我说去掉 getChar() 就可以了。 那么 getChar() 有什么作用呢?我认为它与 getchar() 不同? 不,抱歉,肯定只是getchar() --- 我的错误 @ArminRigo 这是一个有趣的观点,我不知道volatile。谢谢。 【参考方案1】:

当您调用像 getchar 这样的 I/O 函数时,您会锁定某个 I/O 对象,直到函数终止。在多线程程序中无限期地持有锁是非常糟糕的形式,因为这将导致任何试图获取该锁的线程无限期地阻塞。不要在多线程程序中调用阻塞 I/O 函数。

【讨论】:

以上是关于c ++线程等待用户IO('getchar()')在主进程中挂起'Py_Initialize()'的主要内容,如果未能解决你的问题,请参考以下文章

node js异步IO机制

JAVA - IO模型

Linux5种IO模型

深入理解异步I/O+epoll+协程

Unix/Linux 编程:网络编程之 IO模型

Windows系统编程C/C++--互斥量