如果我重復其他人多次提出的相同問題,我很抱歉,但我找不到滿意的答案。因此,再次發布這個簡單的查詢。
問題:據我了解,Linux 中的每個執行緒在內核的任務鏈接串列中都有一個“task_struct”節點。
Linux Version :
#lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
我撰寫了一個 linux 內核模塊來查看“task_struct”的完整串列,并找出哪些“task_struct”節點屬于我的簡單程式(它有一個主執行緒和使用 pthread_create() 函式創建的 4 個執行緒,總共 5 個執行緒) .
下面是我的模塊的核心邏輯,用于找出串列中的所有“task_struct”成員屬于特定的“tgid”(執行緒組 ID)。我的模塊.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched/signal.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MY_NAME");
MODULE_DESCRIPTION("Print a task details");
char * get_task_state(long state)
{
switch (state) {
case TASK_RUNNING:
return "TASK_RUNNING";
case TASK_INTERRUPTIBLE:
return "TASK_INTERRUPTIBLE";
case TASK_UNINTERRUPTIBLE:
return "TASK_UNINTERRUPTIBLE";
case __TASK_STOPPED:
return "__TASK_STOPPED";
case __TASK_TRACED:
return "__TASK_TRACED";
default:
return "UNKNOWN TYPE";
}
}
static void print_task_info(unsigned int tgid)
{
struct task_struct *task_list;
for_each_process(task_list) {
if (task_list->tgid == tgid) {
pr_info("task_struct node : %p\t Name: %s\t PID:[%d]\t TGID:[%d]\t State:%s\n",
task_list, task_list->comm, task_list->pid, task_list->tgid,
get_task_state(task_list->state));
}
}
return;
}
unsigned int arg;
static int notify_param(const char *val, const struct kernel_param *kp)
{
int res = param_set_int(val, kp);
pr_info("notify_param() called.\n");
if (!res) {
print_task_info(arg);
return 0;
}
return -1;
}
const struct kernel_param_ops my_module_param_ops =
{
.set = notify_param,
.get = param_get_int,
};
module_param_cb(arg, &my_module_param_ops, &arg, S_IRUSR|S_IWUSR);
static int __init my_module_init(void)
{
printk("Hello, Linux Kernel");
return 0;
}
static void __exit my_module_exit(void)
{
printk("Bye, Linux Kernel");
return;
}
module_init(my_module_init);
module_exit(my_module_exit);
下面是Makefile:
obj-m = mymodule.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
編譯并加載它:
#make
#insmode mymodule.ko
將此模塊插入內核后,我為 tgid 傳遞一個引數,如下所示。
echo 7196 > /sys/module/mymodule/parameters/arg
'7196' 是一個用戶程式的 pid,它總共有 5 個執行緒(如前所述)。在這里,我希望我應該有 5 個“task_struct”條目,但實際上它只顯示了一個,如下所示:
#dmesg | tail
[ 4432.971557] task_struct node : 000000007bede576 Name: a.out PID:[7196] TGID:[7196] State:TASK_RUNNING
請幫助我理解這種行為,因為我對 Linux 中執行緒的表示方式的理解是錯誤的。
我的理解是,Linux所有的執行程式都是以執行緒的形式執行的,有些執行緒共享記憶體區域(也有相同的'tgid'(執行緒組id,稱為同一行程的執行緒))。
uj5u.com熱心網友回復:
行程和執行緒都使用struct task_struct,但是您需要兩個嵌套回圈來遍歷所有執行緒。外回圈回圈通過行程,內回圈回圈通過該行程的執行緒。
例如:
static void print_task_info(unsigned int tgid)
{
struct task_struct *the_process;
struct task_struct *the_thread;
char comm[TASK_COMM_LEN];
rcu_read_lock();
for_each_process(the_process) {
if (task_tgid_nr(the_process) == tgid) {
for_each_thread(the_process, the_thread) {
pr_info("thread node: %p\t Name: %s\t PID:[%d]\t TGID:[%d]\n",
the_thread, get_task_comm(comm, the_thread),
task_pid_nr(the_thread), task_tgid_nr(the_thread));
}
break;
}
}
rcu_read_unlock();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/430561.html
