popen真的是线程安全的吗?

时间:2019-01-21 14:12:00

标签: multithreading concurrency thread-safety popen

最近,我遇到了调用popen的麻烦,这似乎不是线程安全的。

以下是源代码链接中的代码段:http://androidxref.com/9.0.0_r3/xref/bionic/libc/upstream-netbsd/lib/libc/gen/popen.c

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

static rwlock_t pidlist_lock = RWLOCK_INITIALIZER;

FILE *
popen(const char *command, const char *type)
{
   struct pid *cur, *old;
   ...
   pipe2(pdes, flags)                 // A
   ...
   (void)rwlock_rdlock(&pidlist_lock);     // C
   ...
   switch (pid = vfork()) {                // C.1
     case 0:             /* Child. */
        ...
        _exit(127);
        /* NOTREACHED */
    }

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

   (void)rwlock_unlock(&pidlist_lock); // F
   ...
}

观察上面的代码,它在C处获得了读取锁定,但是在范围内,它在E处进行了一些写入操作。因此,可能会有多个读取线程正在向中的变量“ pidlist”写入数据。在同一时间。

有人知道这是不是真的问题?

1 个答案:

答案 0 :(得分:0)

看看代码,这不是您概述代码的方式。

这是给定链接http://androidxref.com/9.0.0_r3/xref/bionic/libc/upstream-netbsd/lib/libc/gen/popen.c中的粘贴

80FILE *
81popen(const char *command, const char *type)
82{
83  struct pid *cur, *old;
94  if (strchr(xtype, '+')) {
...
100 } else  {
103     if (pipe2(pdes, flags) == -1)
104         return NULL;
105 }
106
...
113
114 (void)rwlock_rdlock(&pidlist_lock);
115 (void)__readlockenv();
116 switch (pid = vfork()) {
117 case -1:            /* Error. */
...
127 case 0:             /* Child. */
...
154     execl(_PATH_BSHELL, "sh", "-c", command, NULL);
155     _exit(127);
156     /* NOTREACHED */
157 }
158 (void)__unlockenv();
159
160 /* Parent; assume fdopen can't fail. */
161 if (*xtype == 'r') {
...
167 } else {
...
173 }
...
179 pidlist = cur;
180 (void)rwlock_unlock(&pidlist_lock);
181
182 return (iop);
183}

do the file stuff (pipe2() or socketpair())
acquire the lock (this will avoid the child doing silly things)
vfork()
on the child, reorganize filedes and execl
on parent do some filedes stuff unlock and return

我看不出问题所在。