【问题标题】:Why instead of adding #include<linux/sched.h> in my code , the code cannot identify task_struct structure为什么不是在我的代码中添加#include<linux/sched.h>,而是代码无法识别task_struct结构
【发布时间】:2016-11-16 06:23:47
【问题描述】:

下面我提到了我的小代码,下面是我对它的疑问 -

1.我打开了 /usr/src/linux-headers-3.13.0-32/include/linux/sched.h 并在那里找到了 struct task_struct 的声明,但是当我尝试声明一个实例时,即变量在包含sched.h头的主函数中的task_struct,那么它也无法识别task_struct,为什么? , 为什么会这样
2. 即使我在我的代码中复制了该头文件的完整代码,即我的主类之外的 .c 文件,编译器也会显示错误以包含许多其他头文件,当我没有复制 sched 的代码时这不是问题.h 在我的 .c 文件中

编译器在第一种情况下显示的错误是 - 'temp' 的存储大小未知

我的代码是(代码只是一个代表视图来告诉我的问题概念)

#include<linux/sched.h>
int main(void)
{
    struct task_struct temp;
    printf("%d",temp.pid);
    return 0;
}

由于概念很清楚,仍然缺少一些东西,请分享您的建议。

【问题讨论】:

  • 您想在实际程序中使用变量temp 做什么。我问是因为很可能有更好的解决方案根本不需要struct task_struct
  • @pts ,今天我正在学习进程,在学习过程中,我了解到操作系统内部使用 task_struct 来存储与进程相关的信息,我只想看到它们通过C代码
  • 假设你知道#include 是什么。您的程序仍然无法按预期运行,因为您没有初始化 temp 变量,所以 temp.pid 包含垃圾。
  • @Gaurav Joshi:查看struct task_struct 在 C 代码中工作的最简单方法是编写内核模块。对于初学者来说,编写内核模块并不容易,因此您可能需要先查找并阅读有关编写 Linux 内核模块的教程,或者请附近的人(可能是您的教授)在您的笔记本电脑上引导您完成整个过程。
  • @pts ,我认为我的代码(即我的C代码)的执行实例将是task_struct的初始化,因为目前我的进程正在执行,我没有想到垃圾值, 顺便感谢你激励我使用内核模块

标签: c linux struct operating-system kernel


【解决方案1】:

我的 Linux 系统 (Ubuntu 14.04) 无法使 struct task_struct 对用户代码可用:

$ rgrep 'task_struct' /usr/include
/usr/include/linux/hdreg.h:} task_struct_t;
/usr/include/linux/capability.h:struct task_struct;

第二个匹配 (struct task_struct;) 只是类型的前向声明。如果在类型声明中没有 { ... },它只是一个前向声明,而在 C(和 C++)中,不可能使用结构的前向声明来创建该类型的变量。这就是您收到 storage size of ... isn't known 错误的原因。

如果要创建struct task_struct 类型的变量,则需要从另一个.h 文件中获取其类型声明,该文件与{ ... } 有它。您可能必须为此安装一个包含内核头文件的包。请参阅您的 Linux 发行版的有关查找和安装软件包的文档。安装包后,您可以使用gcc -I /usr/.../...gcc 指定目录名称以查找.h 文件。

大多数程序(包括所有用户态程序,不包括内核本身和内核模块)不需要创建struct task_struct 类型的变量。如果您在问题中说明您想使用 struct task_struct 做什么,您可能会得到一个建议,以在不使用 struct task_struct 的情况下实现您的目标。

如果你只想打印当前进程的PID,这里是没有struct task_struct的方法:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
  printf("%lld\n", (long long)getpid());
  return 0;
}

【讨论】:

  • 嘿点!你能给我一个相同的参考链接吗
  • @GauravJoshi:我不明白你需要什么链接。如果您无法在网上找到答案,最好单独问一个 StackOverflow 问题(例如,如何找到 .h 文件,如何安装软件包)。
  • @ptr ,看到你让我进退两难,一方面你说 Ubuntu 14.04 不支持 task_struct 受用户控制,相反你说下载内核头文件同样,当我有标头即 sched.h 并在其中声明了 task_struct 时,那么需要任何其他标头
  • 请帮我解决这个问题,因为你是唯一回应的人
  • @Gaurav Joshi:如果你正在编写一个内核模块(使用insmodmodprobe加载),那么你可以使用struct task_struct(和current),否则你可以不。如果你不确定你是否正在编写内核模块,那么你不是。如果您不编写内核模块,但想编写一个,请查找有关编写 Linux 内核模块的在线教程,如果遇到困难,请在 StackOverflow 上单独提问。
【解决方案2】:

Linux 内核头文件并非设计为直接包含在用户空间程序中。即使您这样做,这并不意味着您的代码可以访问此类标头的所有内容,因为 __KERNEL__ 定义阻止了这种情况发生。 Linux 内核仍然试图让用户代码使用内核头文件成为可能,因此有时可以这样做,但您应该坚持在内核代码中使用内核头文件,否则使用 C 库。

This 文章可能会有所帮助。

【讨论】:

    【解决方案3】:

    像这样使用它,sched.h 是 GNU 的一部分

    你可以这样使用:

    #define _GNU_SOURCE
    #ifndef __USE_GNU
    #define __USE_GNU
    #endif
    #include <sched.h>
    

    现在你可以使用sched.h的所有功能了

    【讨论】:

      【解决方案4】:

      "struct task_struct" 无疑存在于 "linux/sched.h" 中。我怀疑您正在以错误的方式构建模块,甚至您的代表性代码看起来也像是在处理用户空间 c 编程风格中的问题。 您应该了解 Linux 代码在各个方面与用户空间 c 程序不同,最基本的是它没有传统的“main”函数作为入口点,而是基于注册的机制。您可以从 @ 阅读有关构建内核模块的信息987654321@

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-30
        • 1970-01-01
        • 2014-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-18
        相关资源
        最近更新 更多