我在Linux上,我正在从我的C spawn应用程序中分配/执行一个新进程.是否也可以更改这些新子进程的命名?
我希望能够识别正在启动的进程,以防出现问题并且我需要手动终止它.目前它们都有相同的名称.
Ama*_*dan 13
我认为这应该有效,以说明原则......
#include <stdio.h>
int main(int argc, char *argv[]) {
argv[0][0] = 65;
sleep(10);
}
Run Code Online (Sandbox Code Playgroud)
将更改名称,并输入"A"而不是第一个字母.CtrlZ暂停,然后运行ps
以查看名称已更改.我不知道,但似乎有点危险,因为有些事情可能依赖argv[0]
.
另外,我尝试将指针本身替换为另一个字符串; 没有雪茄.所以这只适用于strcpy
和字符串短于或等于原始名称.
可能有也可能没有更好的方法.我不知道.
编辑:nonliteral解决方案:如果你正在分叉,你知道孩子的PID(getpid()
在孩子,fork()
父母的结果).只需将它输出到可以读取的地方,然后通过PID杀死孩子.
另一个非文字解决方案:使用另一个名称(ln -s a.out kill_this_a.out
)生成可执行文件的软链接,然后当你执行时,执行链接.名称将是链接的名称.
其中一条评论提到prctl
,但这确实值得自己回答,因为设置argv[0]
并非在所有情况下都有效(它在我的系统上没有任何作用)。
在 Linux 中,至少有两个库调用可以设置线程的名称,两者都限制为 15 个字符加上终止NUL
字节:
pthread_setname_np(...)
其中np
代表“不可移植”,但这可能存在于其他一些操作系统上: https: //linux.die.net/man/3/pthread_setname_npprctl(PR_SET_NAME...)
也是不可移植的: https: //linux.die.net/man/2/prctl这是对不同方法的测试(没有错误处理):
// gcc pstest.c -o pstest -O2 -Wall -Wextra -Werror -Wno-unused -Wno-unused-result -std=gnu99 -pthread -D_GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/prctl.h>
int main(int argc, char *argv[])
{
puts("Initial ps output:");
system("ps | grep pstest");
puts("\npthread_setname_np");
pthread_setname_np(pthread_self(), "setname");
system("ps | grep setname");
puts("\nprctl");
prctl(PR_SET_NAME, (unsigned long)"prctl", 0, 0, 0);
system("ps | grep prctl");
puts("\nargv[0]");
argv[0] = "argv0";
system("ps | grep argv0");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请注意以下命令之后缺少输出argv[0]
:
./pstest
Initial ps output:
17169 pts/0 00:00:00 pstest
pthread_setname_np
17169 pts/0 00:00:00 setname
prctl
17169 pts/0 00:00:00 prctl
argv[0]
Run Code Online (Sandbox Code Playgroud)
这是生产代码中的示例(与往常一样,在 GitHub 上查看代码时请务必记下许可证)
另请参阅这些问题和答案:
根据此评论,prctl(PR_SET_NAME)
仅影响线程的“短名称”。与写入 的效果相同/proc/self/comm
。
要更改“长名称”(/proc/self/cmdline
实际上由htop
和使用ps u
),您需要一些丑陋的黑客(该评论中提到了这一点,但链接已失效)。这种黑客攻击的示例可以在 Chromium 源代码中找到: https: //source.chromium.org/chromium/chromium/src/+/master :content/common/set_process_title_linux.cc