pthread_create()是如何工作的?

11

给定以下内容:

pthread_t thread;
pthread_create(&thread, NULL, function, NULL);
  • pthread_create函数对thread做了什么?

  • thread在加入主线程并终止后会发生什么?

  • 如果在thread已经加入后,执行以下操作会发生什么:

pthread_create(&thread, NULL, another_function, NULL);

4
我被踩了……为什么?这是一个关于编程的具体问题。 - K-RAN
1
+1,了解实现细节总是很不错的。 - Matheus Moreira
pthread_create - gliderkite
1
@MatheusMoreira,在编辑时,你不应该改变问题本身。如果你有更多/类似的问题,你应该单独发布它或在评论中发布。 - P.P
1
我的问题的修订更符合我所寻找的。非常感谢大家,真的很抱歉给你们带来麻烦。 - K-RAN
显示剩余3条评论
2个回答

5

pthread_create函数是一个创建线程的函数,它会返回一个值用于标识新创建的线程。如果创建成功,该值将填充thread参数。如果创建失败,则调用后thread的值未定义。(参考:http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_create.html)

当线程加入到主线程并终止后,对象本身不会发生任何变化,但它所持有的值不再引用任何线程(因此,您无法将其传递给需要pthread_t的函数,如果您不小心这样做,可能会出现ESRCH错误)。

如果在线程已经加入后,您执行了pthread_create,那么和之前一样:如果创建成功,将分配一个值来标识新创建的线程。


我认为你忘了提到pthread_create实际上会创建线程并执行该线程。如果你没有使用pthread_join,主线程将不会等待线程完成而直接继续执行。如果你使用了pthread_join,主线程将在那里等待线程完成。这不是吗? - Chan Kim
这一切都是真的,但我认为问题是关于函数调用对thread对象的影响,而不是它对被该对象标识的执行线程的影响。 - Steve Jessop

2

pthread_create会使用操作系统调用创建一个线程。抽象的优势在于您不需要关心正在发生什么。它将设置变量“ thread”等于标识符,该标识符可用于引用该线程。例如,如果您有多个线程并想取消其中一个,请使用正确的pthread_t标识符调用

pthread_cancel(thread)

以指定您感兴趣的线程。

当线程加入主线程并终止后,线程会发生什么?

在线程终止之前,变量“ 线程”作为获取或标识线程的键/索引。在线程终止之后,键/索引指向的值不再需要有效。您可以保留它并尝试重用它,但这几乎肯定会导致错误。

如果线程加入后,您这样做会发生什么:

pthread_create(&thread, NULL, another_function, NULL);

没问题,因为你给它一个线程的引用,线程的值将被设置为刚刚创建的新线程的标识符。我怀疑它可能与以前相同,但我不会指望它是这样的。

1
你如何知道 pthread_join 不会修改对象。该对象是不透明的。你不能(也不应该)知道每个调用对传递作为参数的 pthread_t 对象做了什么。你只知道它用于标识其他 pthread_* 调用中的线程。 - Martin York
@Loki,pthread_join通过值传递其pthread_t参数;它不能影响其值。它肯定可以修改pthread_t值所标识的“对象”,但这是一个单独的问题,而且Paul的答案甚至从未提到过。这就像free不修改其传递的指针一样。 - Rob Kennedy
1
@RobKennedy: 你在做假设。如果pthread_t是一个指针呢?那么你就可以轻松修改这个对象。但我们忽略了要点。要点是你不知道(也不应该知道)这些函数对对象做了什么。这个对象是不透明的,出于某种原因。 - Martin York
1
即使pthread_t是一个指针,该指针也不会被修改,它被复制到调用中。它所指向的东西可能会被修改,但这就是不透明性的作用。您提出了一个有效的观点,我编辑了回复,试图不涉及讨论的问题。 - Paul Rubel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接