4

I'm writing a little application under Linux (embedded on ARM) that is running two threads. I do a "popen" in a function and this creates a deadlock for the second thread that enters the function. However, the first thread that entered the function first still runs correctly.

Here is some code sample:

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

    }

I really have the felling that I'm missing something important. How could a deadlock happen with popen? Is the problem comming from the standard libc or Linux kernel ?

Any pointer is strongly appreciated !

Regards,

morandg
  • 1,066
  • 3
  • 14
  • 30
  • does the second thread remain blocked till the first one closes the pipe, doesn't it? – Karoly Horvath Jul 29 '11 at 11:43
  • ALWAYS CLOSE YOUR FILE DESCRIPTOR. Sorry I should had add the pclose in my sample code! No, the thread is still stuck when I close the pipe! – morandg Jul 29 '11 at 11:54
  • nono.. I just thought it might be some locking issue. srry – Karoly Horvath Jul 29 '11 at 11:59
  • Problem solved by writing my own class that does the "popen" job, this means, creating pipes, forking, duping, ... I'm even able to add a timeout and kill the command if it doesn't return. Conclusion, better to write your own stuff, you know what is going around! – morandg Jul 29 '11 at 12:55

1 Answers1

2

Since popen does a fork (which is not thread safe), then popen is not thread safe as well.

This question and answers might help you a bit.

Community
  • 1
  • 1
BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • Thanks for your reply! So if I lock my function with mutexes, is it supposed to work? I quickly tried, it doesn't ... How could I avoid this problem? – morandg Jul 29 '11 at 12:09
  • @morandg Can you edit your question. You might have places mutexes at wrong position – BЈовић Jul 29 '11 at 12:23
  • I would be surprised, I locked the whole function! But here you go anyway! – morandg Jul 29 '11 at 12:53
  • 2
    you only need the mutex for the `popen` call, but if it doesn't work with this big lock it won't work that way either. also, if this were really reentrancy issue you should have seen altering behaviour based on the actual timings, sometimes working and sometimes blocking – Karoly Horvath Jul 29 '11 at 12:56
  • I think the problem is from somewhere else as the behavior was the same all the time. I think there is a deeper problem in my application ... I'll give you news if I have some clues! Thanks a lot for all your help anyway ! – morandg Jul 29 '11 at 13:04