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

史密斯

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

这是一个非常简单的实现:

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...
}

我使用此函数创建2个线程并将其分离

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

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

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

唯一有效的锁定方式是

pthread_lock(&lock1);
popenReturn = popen(buffer,"w");
pclose(popenReturn);    
pthread_unlock(&lock1);

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

这是手册页错误并且popen()和pclose()线程不安全的情况吗?如果是这样,是否有可以解决此问题的锁定解决方案?

否则,我在执行中是否做错了什么?

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

约翰·布林格

gnome-terminal您的示例中,命令可能不是一个不错选择,我当然希望它只是一个示例。我不清楚您为什么不直接popen()输入ssh命令。更多关于gnome-terminal以后。

你写

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

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

现在,我发现popen()对于呈现GUI的程序(甚至与之类似的简单性)来说,这非常有问题gnome-terminal,但gnome-terminal由于以下事实,我倾向于猜测这特别棘手:

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

gnome终端手册页

我相信您会理解,单进程行为可能会对期望创建和管理独立子进程的API造成严重破坏。我怀疑这是观察到的两个呼叫行为不同的原因。

此外,您应该检查函数调用的返回值,您的示例未演示该返回值。我不确定您popen()和/或pclose()是否应该发信号通知错误,但我认为这是一种很好的可能性。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章