使用popen时发生死锁

4
我正在Linux系统下编写一个小应用程序(嵌入在ARM设备中),此程序运行两个线程。我在一个函数中使用了“popen”命令,导致第二个线程进入该函数时发生死锁。然而,第一个进入该函数的线程仍然可以正确运行。
以下是一些代码示例:
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

    int sendCommand(
        const std::string& command, std::string& answer)
    {
      FILE* fd;                           // File descriptor to command output
      char answer_c[COMMAND_BUFFER_SIZE]; // The answer as char[]
      int answerLength = 0;               // The length of the answer

      pthread_mutex_lock( &mutex1 );

      // A probe
      cout << "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" << endl;

      fd = popen(command.c_str(), "r"); // <- Second thread entering is stuck here ...
      if(fd <= 0)
      {
        cout << "couldn't popoen !" << endl;
        return -1;
      }

      // A probe, never showed by second thread entering the function
      cout << "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZzz" << endl;

      // ... Omitted code ...
      // Close the file descriptor
      pclose(fd);
      pthread_mutex_unlock( &mutex1 );

    }

我真的感觉自己错过了很重要的东西。使用popen时,死锁是如何发生的?这个问题是来自标准libc还是Linux内核?任何提示都将不胜感激!
问候,

第二个线程会一直阻塞直到第一个线程关闭管道,是吗? - Karoly Horvath
请始终关闭您的文件描述符。抱歉,我应该在示例代码中添加pclose!不,当我关闭管道时,线程仍然被卡住了! - morandg
不好意思,我只是觉得可能是一些锁定问题。抱歉。 - Karoly Horvath
通过编写自己的类来解决问题,该类执行“popen”任务,这意味着创建管道、分叉、复制等操作。我甚至能够添加超时并在命令未返回时终止它。总之,最好编写自己的代码,这样你就知道发生了什么! - morandg
1个回答

2

由于popen执行了fork操作(这是不安全的线程),因此popen也不是线程安全的。

这个问题和答案可能会对你有所帮助。


谢谢您的回复!那么,如果我使用互斥锁来锁定我的函数,它应该可以工作吗?我尝试了一下,但好像不行...我该如何避免这个问题呢? - morandg
@morandg 你能编辑一下你的问题吗?你可能把互斥锁放错位置了。 - BЈовић
我会感到惊讶,我锁定了整个函数!但是无论如何,这里是! - morandg
2
你只需要在popen调用时使用互斥锁,但如果这个大锁不能正常工作,那么用这种方式也行不通。另外,如果这真的是可重入问题,你应该会根据实际时间看到改变行为,有时候能够工作,有时候会阻塞。 - Karoly Horvath
我认为问题来自其他地方,因为行为始终如一。我认为我的应用程序存在更深层的问题... 如果我有一些线索,我会给你们消息!无论如何,非常感谢你们的所有帮助! - morandg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接