首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pclose()在多线程环境中过早返回(Solaris 11)

pclose()在多线程环境中过早返回(Solaris 11)
EN

Stack Overflow用户
提问于 2018-01-08 23:31:45
回答 1查看 102关注 0票数 2

我正在尝试实现一个工具,该工具启动2个ssh连接并执行一个需要root权限的脚本。

下面是一个非常简单的实现:

代码语言:javascript
复制
void* SshConnection(void* args)
{
   char buffer[5000];
   FILE* popenReturn = NULL;

   //get the hostname to connect to
   const char* hostname = (const char*)args;

   snprintf(buffer, sizeof(buffer),
           "/usr/bin/gnome-terminal -x bash -c \""
           "ssh -t user@%s "
           "-i /home/user/.ssh/key.key "
           "\\\"/home/user/DoRootThings.bash\\\" ",hostname);

   popenReturn = popen(buffer,"w");
   pclose(popenReturn);

   //...connect to the host again later on and look at results of DoRootThings.bash...
}

我使用这个函数创建了两个线程,并将它们分开。

考虑到上面的实现,我希望使用-i ssh选项提供的键登录到“用户”帐户的2个gnome终端是可见的。脚本应该已经执行,并且正在等待提供根密码,而两个执行线程都在pclose()处停止执行,同时等待各自的gnome终端返回。

相反,两个gnome终端会打开,它们正在等待根密码。其中一个线程的执行在pclose()处停止,而其他线程pclose()则立即返回。然后这个线程继续查看DoRootThings.bash的结果,没有任何结果,因为它仍然在等待密码的执行!

popen()和pclose()的Solaris手册页声称它们都是线程安全的。为了安全起见,我尝试过多种形式的锁定,但都没有用。

唯一有效的锁定形式是

代码语言:javascript
复制
pthread_lock(&lock1);
popenReturn = popen(buffer,"w");
pclose(popenReturn);    
pthread_unlock(&lock1);

但这给我留下了一个单一的解决方案。

这是否是手册页出错,而popen()和pclose()线程不安全的情况?如果是这样的话,是否有一个锁定解决方案来解决这个问题?

否则,我在执行过程中难道没有做正确的事情吗?

注意:我最初使用的是system(),而不是popen()和pclose(),但这不是线程安全调用,而system()的Solaris手册页则使用了popen()和pclose()。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-09 00:23:50

对于您的示例来说,gnome-terminal命令可能是一个糟糕的选择,我当然希望它只是一个示例。我不清楚为什么您不直接使用popen()命令ssh。稍后将更多地介绍gnome-terminal

你写

考虑到上面的实现,我希望使用-i ssh选项提供的键登录到“用户”帐户的2个gnome终端是可见的。脚本应该已经执行,并且正在等待提供根密码,而两个执行线程都在pclose()处停止执行,同时等待各自的gnome终端返回。

但这不是我所期望的。调用pclose()应该先关闭流,另一端的进程将在其标准输入上将其视为EOF。然后,该函数将等待子进程终止,但该进程不应阻止从其标准输入读取的任何尝试。我通常希望两个pclose()调用都能快速返回。

现在,我发现popen()是一个非常值得怀疑的程序,它提供了一个图形用户界面,甚至像gnome-terminal的程序一样简单,但是我倾向于猜测gnome-terminal是特别棘手的,因为事实上

默认情况下,所有GNOME终端共享一个进程,从而减少内存使用。可以通过使用--disable-factory选项启动gnome终端来禁用此功能。

(gnome终端手册页)

我相信您可以理解,单进程行为很可能会破坏期望创建和管理独立子进程的API。我怀疑这就是这两个电话在行为上观察到的差异的原因。

此外,您应该检查函数调用的返回值,您的示例没有演示这些值。我不确定您的popen()和/或pclose()是否存在信令错误,但我认为这是一个很好的可能性。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48159534

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档