我在Linux上,我正在从我的C spawn应用程序中分配/执行一个新进程。是否也可以更改这些新子进程的命名?
我希望能够识别正在启动的进程,以防出现问题,我需要手动终止它。目前它们都有相同的名称。
答案 0 :(得分:13)
我认为这应该有效,以说明原则......
#include <stdio.h>
int main(int argc, char *argv[]) {
argv[0][0] = 65;
sleep(10);
}
将更改名称,并输入“A”而不是第一个字母。 CtrlZ暂停,然后运行ps
以查看名称已更改。我不知道,但似乎有点危险,因为有些事情可能取决于argv[0]
。
另外,我尝试将指针本身替换为另一个字符串;没有雪茄。因此,这只适用于strcpy
和字符串短于或等于原始名称。
可能有也可能没有更好的方法。我不知道。
编辑:非文字解决方案:如果你正在分叉,你就知道孩子的PID(孩子的getpid()
,父母的fork()
的结果)。只需将它输出到可以读取的地方,然后通过PID杀死孩子。
另一个非文字解决方案:使用其他名称(ln -s a.out kill_this_a.out
)创建可执行文件的软链接,然后当您执行时,执行链接。名称将是链接的名称。
答案 1 :(得分:0)
其中一条评论提到了prctl
,但这确实值得回答,因为设置argv[0]
并不能在所有情况下都起作用(在我的系统上不起作用)。
在Linux中,至少有两个库调用来设置线程的名称,均限制为15个字符以及终止的NUL
字节:
pthread_setname_np(...)
,其中np
表示“不可移植”,但是在某些其他操作系统上也可能存在:https://linux.die.net/man/3/pthread_setname_np prctl(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;
}
注意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]
Here's an example in production code(一如既往,在GitHub上查看代码时,请务必注意许可证)
另请参阅以下问题和答案:
答案 2 :(得分:0)
根据this comment,prctl(PR_SET_NAME)
仅影响线程的“短名称”。它的作用与写入/proc/self/comm
的作用相同。
要更改“长名”(/proc/self/cmdline
和htop
实际使用的“长名”),您需要进行一些丑陋的修改(该注释中已提及,但链接已失效) )。可在Chromium源代码中找到这种黑客的示例:https://cs.chromium.org/chromium/src/services/service_manager/embedder/set_process_title_linux.cc?sq=package:chromium&g=0
答案 3 :(得分:0)
这是不可移植的骇客:
/*
* Sets process title, truncating if there is not enough space,
* rather than causing memory corruption.
*/
void set_title_np(int argc, char **argv, const char *title) {
// calculate available size
size_t space = 0;
for (int i = 0; i < argc; i++) {
size_t length = strlen(argv[i]);
space += length + 1; // because of terminating zero
}
memset(argv[0], '\0', space); // wipe existing args
strncpy(argv[0], title, space - 1); // -1: leave null termination, if title bigger than space
}
答案 4 :(得分:-1)
以下代码示例会将进程名称更改为“Testing”。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[]) {
char* temp = (char*) malloc (20);
strcpy(temp, "Testing");
temp[7] = 0;
printf("Argv[0] --> %s\n", argv[0]);
argv[0] = temp;
printf("Argv[0] --> %s\n", argv[0]);
return 0;
}
以上程序的输出是:
./ a.out的
Argv [0] - &gt; ./a.out
Argv [0] - &gt;测试
argv [0]包含进程的名称。