pclose() 在多线程环境中过早返回 (Solaris 11)
pclose() prematurely returning in a multi-threaded environment (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 个线程并将它们分离
鉴于上述实施,我希望 2 个 gnome 终端可见,它们已使用 -i ssh 选项提供的密钥登录到 'user' 帐户。该脚本应该已经执行并正在等待提供 root 密码,同时两个执行线程都已在 pclose() 处停止,同时等待各自的 gnome 终端 return.
而是打开了 2 个 gnome 终端,它们正在等待 root 密码。其中 1 个线程的执行在 pclose() 处停止,而其他线程 pclose() 立即停止 returns。然后该线程继续查看 DoRootThings.bash 的结果,但没有任何结果,因为它仍在等待密码执行!
popen() 和 pclose() 的 Solaris 手册页声称它们都是线程安全的。为了保险起见,我尝试了多种形式的锁定都无济于事。
唯一有效的锁定形式是
pthread_lock(&lock1);
popenReturn = popen(buffer,"w");
pclose(popenReturn);
pthread_unlock(&lock1);
但这给我留下了一个单线程解决方案。
这是手册页错误的情况,popen() 和 pclose() 不是线程安全的吗?如果是这样,是否有解决此问题的锁定解决方案?
否则,我是不是在我的实现中做错了什么?
注意:我最初使用 system() 而不是 popen() 和 pclose() 但这不是线程安全的调用,system() 的 Solaris 手册页推荐 popen() 和 pclose()
gnome-terminal
命令对于您的示例来说可能是一个糟糕的选择,我当然希望它 只是 一个示例。我不清楚您为什么不直接 popen()
ing ssh
命令。更多关于 gnome-terminal
稍后。
你写
Given the above implementation I would expect 2 gnome-terminals to be
visible that have logged into the 'user' account using they keys
provided with the -i ssh option. The script should have been executed
and is waiting for the root password to be provided while both threads
of execution have stopped at pclose() while waiting for their
respective gnome-terminals to return.
,但这不是 I 所期望的。调用 pclose()
应该首先关闭流,另一端的进程将在其标准输入上将其视为 EOF。然后该函数将等待子进程终止,但该进程不应阻止任何从其标准输入读取的尝试。我通常希望 both pclose()
快速调用 return。
现在我发现 popen()
一个显示 GUI 的程序非常值得怀疑,即使是像 gnome-terminal
一样简单的程序,但我倾向于猜测 gnome-terminal
由于
这一事实而特别棘手
By default, all GNOME terminals share a single process, reducing memory usage. This can be disabled by starting gnome-terminal with the --disable-factory
option.
我相信您能理解单进程行为可能会对希望创建和管理单独子进程的 API 造成严重破坏。我怀疑这就是观察到的两个调用行为差异的原因。
此外,您应该检查您的函数调用的 return 值,您的示例没有演示这些值。我不确定你的 popen()
和/或 pclose()
应该是信号错误,但我认为它很有可能。
我正在尝试实现一个启动 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 个线程并将它们分离
鉴于上述实施,我希望 2 个 gnome 终端可见,它们已使用 -i ssh 选项提供的密钥登录到 'user' 帐户。该脚本应该已经执行并正在等待提供 root 密码,同时两个执行线程都已在 pclose() 处停止,同时等待各自的 gnome 终端 return.
而是打开了 2 个 gnome 终端,它们正在等待 root 密码。其中 1 个线程的执行在 pclose() 处停止,而其他线程 pclose() 立即停止 returns。然后该线程继续查看 DoRootThings.bash 的结果,但没有任何结果,因为它仍在等待密码执行!
popen() 和 pclose() 的 Solaris 手册页声称它们都是线程安全的。为了保险起见,我尝试了多种形式的锁定都无济于事。
唯一有效的锁定形式是
pthread_lock(&lock1);
popenReturn = popen(buffer,"w");
pclose(popenReturn);
pthread_unlock(&lock1);
但这给我留下了一个单线程解决方案。
这是手册页错误的情况,popen() 和 pclose() 不是线程安全的吗?如果是这样,是否有解决此问题的锁定解决方案?
否则,我是不是在我的实现中做错了什么?
注意:我最初使用 system() 而不是 popen() 和 pclose() 但这不是线程安全的调用,system() 的 Solaris 手册页推荐 popen() 和 pclose()
gnome-terminal
命令对于您的示例来说可能是一个糟糕的选择,我当然希望它 只是 一个示例。我不清楚您为什么不直接 popen()
ing ssh
命令。更多关于 gnome-terminal
稍后。
你写
Given the above implementation I would expect 2 gnome-terminals to be visible that have logged into the 'user' account using they keys provided with the -i ssh option. The script should have been executed and is waiting for the root password to be provided while both threads of execution have stopped at pclose() while waiting for their respective gnome-terminals to return.
,但这不是 I 所期望的。调用 pclose()
应该首先关闭流,另一端的进程将在其标准输入上将其视为 EOF。然后该函数将等待子进程终止,但该进程不应阻止任何从其标准输入读取的尝试。我通常希望 both pclose()
快速调用 return。
现在我发现 popen()
一个显示 GUI 的程序非常值得怀疑,即使是像 gnome-terminal
一样简单的程序,但我倾向于猜测 gnome-terminal
由于
By default, all GNOME terminals share a single process, reducing memory usage. This can be disabled by starting gnome-terminal with the
--disable-factory
option.
我相信您能理解单进程行为可能会对希望创建和管理单独子进程的 API 造成严重破坏。我怀疑这就是观察到的两个调用行为差异的原因。
此外,您应该检查您的函数调用的 return 值,您的示例没有演示这些值。我不确定你的 popen()
和/或 pclose()
应该是信号错误,但我认为它很有可能。