【问题标题】:Linux process ID and thread IDLinux 进程 ID 和线程 ID
【发布时间】:2011-12-19 18:43:48
【问题描述】:

假设我们有很多用户进程在 Linux 上运行。每个进程都有许多线程在运行。

我可以通过调用getpid()获取进程ID,它的返回值是一个整数。

我可以通过调用pthread_self()获取线程ID,它的返回值是一个名为pthread_t的不透明类型。

现在我需要将进程 ID(一个 int,通常为 4 个字节)和线程 ID(pthread_t,需要计算出多少字节)存储在共享内存中,以便我以后可以使用这两个 ID用于识别该特定线程并检查该线程是否仍在运行的信息。

我发现许多在线资源将pthread_t 转换为unsigned intunsigned long。由于我不希望在转换过程中丢失任何数据,我应该如何处理pthread_t 数据,使其成为固定大小的数据(如前所述,我需要将线程信息存储在共享内存中)。

另外,我以后应该如何通过进程 ID 和线程 ID 的组合来识别该特定线程?如何检查线程是否仍在运行?

【问题讨论】:

  • 进程ID和线程ID可以重复使用,所以我相信你的整个方法是有缺陷的......
  • @Nemo 你是对的。让我们假设不同的进程和线程总是有不同的 ID 来区分关注点。

标签: c++ c linux process pthreads


【解决方案1】:

如果你想在任何地方存储pid_tpthread_t,你应该使用它们各自的类型(即“pid_t”和“pthread_t”)。因此,如果您想将它们存储在某个共享内存中,请发送memcpy() 以将它们保存到那里。

至于通过 PID 和 TID 的组合识别特定线程,请参阅 Nemo 的评论。

如果您确实假设它们会存在,您可以让程序查看 /proc 以找到适当的 pid 目录,并在 /proc/<pid>/task 中查找线程。

【讨论】:

  • 它们是不透明的;除了“我不知道具体细节的某些块”之外,您不应该尝试以任何方式使用它们,因为它们的实现随时可能发生变化。
  • 所以 memcpy() 可以计算出要为我复制多少字节?那么我需要做的是保留一块足够大的内存来容纳任何 pthread_t 类型?顺便说一句,检查 /proc//task 是获取该特定线程状态的唯一方法吗?
  • memcpy(dest, src, sizeof(pthread_t)) 应该能够复制任何pthread_tpid_t 也是如此。至于使用 proc 文件系统,我相信这是 Linux 的做法。我不确定是否还有其他(或更好的)方法。如果您希望它们在一起,我建议您使用结构,就像 Matteo Italia 建议的那样。
  • 我想为每个进程和线程 ID 对保留相同数量的内存。在同一个系统上,sizeof(pthread_t) 和 sizeof(pid_t) 是否总是给我们相同的大小?
  • @TerryLiYifeng:是的,它们应该总是产生相同的大小(对自己,不一定对彼此)。 sizeof() 值在编译时确定,pthread_tpid_t 与其他类型一样,对于给定系统具有固定大小。
【解决方案2】:

您可以使用pthread_join 作为检测完成的粗略方法,但我确信这不是您想要的。相反,您必须自己通过创建线程完成标志来处理这个问题。设置此标志的一个好方法是在 pthread 清理处理程序中。看到这个相关的post

【讨论】:

    【解决方案3】:

    你为什么不把它们打包成struct

    typedef struct
    {
        int procID;
        pthread_t threadID;
    
    } ProcThreadID;
    

    不用担心pthread_t的具体底层类型(毕竟我们是C语言的,所以一切都是POD,可以用memcpy盲目复制)。

    您可以使用sizeof 运算符轻松获取其大小:

    size_t ptIDSize = sizeof(ProcThreadID);
    

    您可以使用简单的memcpy 将其复制到任何您想要的地方。

    【讨论】:

    • 我必须将 pthread_t 数据序列化到共享内存中,所以我不确定它会如何。
    • 由于 pthread_t 是 C 数据类型的一些 typedef,它可以通过 memcpy 根据定义进行复制。如果是 C++(对象可以有复制构造函数、重载赋值运算符、vtable 指针和其他隐藏的东西),你应该小心,但这里根本没有危险。
    • 我要用这个。顺便说一句,知道如何通过进程 ID 和线程 ID 识别特定线程并检查它是否仍在运行?
    【解决方案4】:

    thread ids 在进程中运行的命令

    $ ps -eLf | grep 14965 
    UID        PID              PPID     LWP           C  NLWP STIME TTY      TIME     CMD 
    root       14965            14732    14965         0  201  15:28 pts/10   00:00:00 ./a.out 
    root       14965            14732    14966         0  201  15:28 pts/10   00:00:00 ./a.out 
    root       14965            14732    14967         0  201  15:28 pts/10   00:00:00 ./a.out 
    root       14965            14732    14968         0  201  15:28 pts/10   00:00:00 ./a.out 
    root       14965            14732    14969         0  201  15:28 pts/10   00:00:00 ./a.out 
    root       14965            14732    14970         0  201  15:28 pts/10   00:00:00 ./a.out 
    root       14965            14732    14971         0  201  15:28 pts/10   00:00:00 ./a.out 
    root       14965            14732    14972         0  201  15:28 pts/10   00:00:00 ./a.out
    

    这里的第 4 列 (LWP) 显示了 ID 14965 进程中运行的所有线程

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-24
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多