2009-11-09 52 views
2

我见过一些popen()/ pclose()的实现。他们都使用的PID的静态列表,并没有锁定:或者popen - 锁还是不线程安全?

static int *pids; 
static int fds; 

if (!pids) { 
     if ((fds = getdtablesize()) <= 0) 
      return (NULL); 
     if ((pids = malloc(fds * sizeof(int))) == NULL) 
      return (NULL); 
     memset(pids, 0, fds * sizeof(int)); 
    } 

此,所谓的NetBSD:

static struct pid { 
    struct pid *next; 
    FILE *fp; 
    pid_t pid; 
} *pidlist; 

    /* Link into list of file descriptors. */ 
    cur->fp = iop; 
    cur->pid = pid; 
    cur->next = pidlist; 
    pidlist = cur; 

它是什么样子 - 一个不是线程安全的实现?还是我错过了明显的东西?

回答

3

如果libc被配置为可重入(它可能是),GNU libc implementation是线程安全的。但是,对于libc的其他实现,情况可能并非如此。

+0

是的,我看到它锁定了孩子的名单。这好多了。感谢您的链接。 我宁愿popen返回一个pid,然后我把它传递给pclose,但是在这种情况下这不是libc的选项 – 2009-11-11 11:39:40

3

我不认为你错过了明显的东西。我没有看到使用popen()或者要求它是线程安全的任何线程安全参考。因此,您应该将其视为非线程安全的。

+0

我记得线程得到支持时,手册页用于明确告诉你函数是安全还是不安全。现在我期望一个功能是安全的,它不会告诉其他.. – 2009-11-09 17:41:43

+2

这将是很好的。但是 - 我会扭转你的期望 - 除非作者真的想到线程问题,否则函数通常是不安全的。如果在手册页中没有提及,那么他们可能没有考虑它。 – Aaron 2009-11-09 17:44:03

+0

至少在Linux上,联机帮助页不一定是编写实现的glibc人编写的。 – bdonlan 2009-11-09 18:04:18