【问题标题】:what is the value range of thread and process id?线程和进程id的取值范围是多少?
【发布时间】:2013-05-17 00:12:43
【问题描述】:

forkpthread_create 将返回进程 ID 或线程 ID。

但是我不知道这些id的取值范围。

现在我想制作一个查找表,在每个条目中都有一个用于线程 ID 的项目/字段。 每个条目的结构如下:

 typedef struct {
   int seq;
   pthread_t tid;
   ...
 } entry_t;

当我没有得到线程的 tid 时,我想为一个无效的 tid 分配一个值(很快这个字段将被一个有效的填充,但在此之前fill 函数将检查pid是否有效)。那么,线程和进程id的取值范围是多少?

【问题讨论】:

  • pthread_create() 返回 0 或错误号;它设置了通过指针传递给它的pthread_t 结构,但是pthread_t 类型没有记录的结构。 fork() 返回的 PID 是 int 主题的变体;它们是 32 位数字,尽管很少使用所有 32 位(但使用了超过 16 位)。 Linux有一个gettid()函数返回一个线程ID;返回类型为pid_t,与fork()getpid()相同。它不是标准功能(根据我正在查看的文档,它是在内核 2.4.11 中添加的)。
  • 有没有可能tid = 0?
  • @misteryes:请注意gettid()(tid)返回的值与pthread_create()成功调用写入第一个参数的值无关。

标签: c linux multithreading multiprocessing


【解决方案1】:

pthread_t 类型是完全不透明的。您只能将其与 pthread_equal 函数进行比较,并且没有与任何有效线程 ID 不同的保留值,尽管这样的值可能会添加到 POSIX 标准的下一个版本中。因此,您需要在线程 ID 旁边存储第二个字段来跟踪它是否有效。

【讨论】:

  • 也许 0 可能是一个不同的值?
  • 0 甚至不一定是值,因为 pthread_t 未指定为标量类型。它可以是结构或联合。提议添加到 POSIX 的保留值将是一个不透明的宏,仅用于分配和传递给 pthread_equal
  • 我只是担心如果我在字段中输入0,然后真的有一个有效的tid = 0,那么就会发生冲突。因为我有超时,当到了超时,我会判断tid是否还是0,如果是我就删除。但是如果真的有有效的tid=0,那我的删除就错了!
  • 我告诉过你把 0 不是一个可移植的解决方案。它可能适用于 Linux 上的常见线程实现,但一般不会起作用。使用单独的字段来标记您是否拥有有效的线程 ID。
  • @liuml07:不。将无效的线程 ID 传递给 pthread_kill 会调用未定义的行为。如果幸运的话,它会使您的应用程序崩溃。如果你不走运,它可能会给你错误的答案或更糟。
【解决方案2】:

pid的最大值是可变的,默认为32768,也就是short int的最大值的大小。并且可以兼容早期版本的UNIX。

您可以在 /proc/sys/kernel/pid_max 中查看和更改它。

顺便说一句,

进程 ID 0 通常是调度程序进程,通常称为 交换者。磁盘上没有程序对应这个进程,即 内核的一部分,被称为系统进程。进程 ID 1 是 通常是 init 进程,并在结束时由内核调用 引导程序。这个过程的程序文件是 /etc/init 在旧版本的 UNIX 系统中是 /sbin/init 在 较新的版本。这个进程负责启动一个 UNIX 内核启动后的系统。 --APUE

tid 仅在其所属进程的上下文中才有意义。 在不同的 UNIX 家族中,pthread_t 不是同一个类型,如

Linux 2.4.22 对 pthread_t 数据使用无符号长整数 类型。 Solaris 9 将 pthread_t 数据类型表示为无符号 整数。 FreeBSD 5.2.1 和 Mac OS X 10.3 使用指向 pthread 的指针 pthread_t 数据类型的结构。 --APUE

所以你不能简单地告诉它的范围。

但是threads_max表示一个进程最多有多少个线程,你可以在/proc/sys/kernel/threads-max中查看和更改。

【讨论】:

  • 这表示我可以用pid=0表示无效,但是不能用tid=0...
  • @misteryes 如果 tid 是指向 pthread 结构的指针,tid=0 表示 tid = NULL,这是无效的。你最好先检查系统中 tid 的类型。
  • 请注意,在非 Linux 系统上,PID 可能不限于 32K(作为特定示例,在 Mac OS X 上,它在 PID = 99999 之后换行)。这不会使这个答案无效(问题被标记为 Linux),但要小心。我记得在 AIX 上看到 6 位 PID,但我无法访问 AIX 来确认这一点。
  • 不要为此使用 pthread_t。这是 pthreads 库中线程的线程描述符,就像 Windows 中的 HANDLE,它们将其命名为一些“线程 id”。更准确地说“这是内部图书馆价值”。您不知道库中保留了哪些句柄值。值可能等于系统中的 TID,也可能不相等,例如,它们可以是库内某个数组中的某个索引。为此,您应该使用线程的线程 ID。要获取线程 ID,您可以使用 syscall(SYS_gettid)。它将等于 htop 中的 TID。正如@vvy 所写,进程 ID 0 通常是调度程序,1 是初始化。
【解决方案3】:

正如其他人指出的那样,没有定义表示无效 pthread-id 的值。

解决此问题的一种方法可能是修改描述线程的结构,如下所示:

typedef struct {
  int seq;
  pthread_t pthread;
  int pthread_is_valid; /* set this to 0 on initialisation of the structure 
                          and change it be 1 if pthread_create() was successfull. */
  ...
} entry_t;

另外我建议不要调用pthread_create() 的第一个参数tid 设置的值,因为这会导致名称与gettid() 重新调整的内容不明确,在Linux 下实际上是一个进程ID。


作为无效进程 ID -1 应该这样做。

【讨论】:

    【解决方案4】:

    我认为为什么不能通过将定义的错误值分配给 tid 本身来跟踪无效的线程 id。在创建查找表时,如果在表增长时继续向结构添加更多成员,则大小可能会受到限制。

    /* 线程标识符 */ typedef unsigned long int pthread_t;

    在检查 pthread_create 结果时,您可能分配了自己定义的错误值。

    例如: pthread_create 失败 - 将 say -ve 值分配给 tid 。因此,在查找时,您可以验证检查您自己的 #define -ve 值。

    【讨论】:

      猜你喜欢
      • 2023-03-25
      • 2013-07-08
      • 1970-01-01
      • 2013-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 2013-07-25
      相关资源
      最近更新 更多