我是Pthreads的新手,我正在尝试理解它。我看到了一些示例,如以下内容。
我可以看到 main()
被API pthread_exit()
阻止,并且我看到了示例,其中主函数被API pthread_join( )
。我无法理解何时使用什么?
我指的是以下网站 - httpps://computing.llnl.gov/tutorials/pthreads/pthreads/ 。我无法获得何时使用 pthread_join()
以及何时使用 pthread_exit()
的概念。
有人可以解释吗?此外,将不胜感激的是Pthreads的良好教程链接。
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
有时会意识到另外一件事
pthread_cancel(thread);
pthread_join(thread, NULL);
,您想在执行线程时取消线程。
您可以使用pthread_cancel(thread);。
但是,请记住,您需要启用Pthread Cancel支持。
另外,取消时清理代码。
thread_cleanup_push(my_thread_cleanup_handler, resources);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
static void my_thread_cleanup_handler(void *arg)
{
// free
// close, fclose
}
I am new to pthreads, and I am trying to understand it. I saw some examples like the following.
I could see that the main()
is blocked by the API pthread_exit()
, and I have seen examples where the main function is blocked by the API pthread_join()
. I am not able to understand when to use what?
I am referring to the following site - https://computing.llnl.gov/tutorials/pthreads/. I am not able to get the concept of when to use pthread_join()
and when to use pthread_exit()
.
Can somebody please explain? Also, a good tutorial link for pthreads will be appreciated.
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
Realized one more thing i.e.
pthread_cancel(thread);
pthread_join(thread, NULL);
Sometimes, you want to cancel the thread while it is executing.
You could do this using pthread_cancel(thread);.
However, remember that you need to enable pthread cancel support.
Also, a clean up code upon cancellation.
thread_cleanup_push(my_thread_cleanup_handler, resources);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
static void my_thread_cleanup_handler(void *arg)
{
// free
// close, fclose
}
发布评论
评论(10)
唔。
:
这似乎与local main()螺纹变量保持可访问的想法背道而驰。
Hmm.
POSIX pthread_exit
description from http://pubs.opengroup.org/onlinepubs/009604599/functions/pthread_exit.html:Which seems contrary to the idea that local main() thread variables will remain accessible.
在主线程中使用
pthread_exit
(代替pthread_join
),将使主线程处于已倒闭(Zombie)状态。由于不使用pthread_join
,因此终止的其他可加入线程也将保留在僵尸状态,并导致资源泄漏。另一点是将主线程保持在已停用状态,而其他线程正在运行时可能会在各种条件下导致相关问题,例如在主线程中分配了资源或在其他线程中使用的主线程局部变量。
同样,仅在流程退出时才会发布所有共享资源,它不能保存任何资源。因此,我认为应避免使用
PTHREAD_EXIT
代替PTHREAD_JOIN
。Using
pthread_exit
in the main thread(in place ofpthread_join
), will leave the main thread in defunct(zombie) state. Since not usingpthread_join
, other joinable threads which are terminated will also remain in the zombie state and cause resource leakage.Another point is keeping the main thread in the defunct state, while other threads are running may cause implementation dependent issues in various conditions like if resources are allocated in main thread or variables which are local to the main thread are used in other threads.
Also, all the shared resources are released only when the process exits, it's not saving any resources. So, I think using
pthread_exit
in place ofpthread_join
should be avoided.当调用pthread_exit()时,调用线程堆栈不再可作为任何其他线程的“活动”内存。所有其他线程仍然可以使用.DATA,.TEXT和.BSS部分“静态”内存分配。因此,如果您需要将某些内存值传递到pthread_exit()中,以使其其他一些pthread_join()呼叫者查看,则需要“可用”呼叫pthread_join()的线程。它应与malloc()/new分配,分配在pthread_join threads stack上,1)pthread_join呼叫者传递给pthread_create或以其他方式可用于the thread call pthread_exit()的堆栈值,或其他可用价值。
了解如何在线程堆栈之间管理内存,而值存储在.data/.bss内存部分中,这些内存用于存储宽值。
When pthread_exit() is called, the calling threads stack is no longer addressable as "active" memory for any other thread. The .data, .text and .bss parts of "static" memory allocations are still available to all other threads. Thus, if you need to pass some memory value into pthread_exit() for some other pthread_join() caller to see, it needs to be "available" for the thread calling pthread_join() to use. It should be allocated with malloc()/new, allocated on the pthread_join threads stack, 1) a stack value which the pthread_join caller passed to pthread_create or otherwise made available to the thread calling pthread_exit(), or 2) a static .bss allocated value.
It's vital to understand how memory is managed between a threads stack, and values store in .data/.bss memory sections which are used to store process wide values.
将此代码复制并粘贴到GDB上。在线GDB可以自己看。
确保您了解一旦创建线程,该过程与Main同时运行。
我想证明有时您需要在此示例中首先使用信号量首先运行代码段。
注意到“在螺纹之前”之后,如果从上到下是线性在螺纹之前,我是线性的,我是线程,我是线程,螺纹之后。但是在这种情况下,我们阻止主运行进一步运行,直到func_t释放信号量为止。可以使用 https://www.onlinegdb.com/ 来验证结果。
Copy and paste this code on a gdb. Onlinegdb would work and see for yourself.
Make sure you understand once you have created a thread, the process run along with main together at the same time.
I would want to demonstrate how sometimes you would need to have a segment of code running first using semaphore in this example.
Noticed how fun_t is being ran after "before thread" The expected output if it is linear from top to bottom would be before thread, I'm thread, after thread. But under this circumstance, we block the main from running any further until the semaphore is released by func_t. The result can be verified with https://www.onlinegdb.com/
如OpenPub文档中所述,
将退出调用它的线程。
在您的情况下,由于主要调用它,Main thread 将终止,而您的产卵线程将继续执行。这主要在
主线程仅需要产生线程并留下线程完成其作业
终止,否则暂停已调用它的线程的执行
除非目标线程
在主线程中处理。
As explained in the openpub documentations,
pthread_exit()
will exit the thread that calls it.In your case since the main calls it, main thread will terminate whereas your spawned threads will continue to execute. This is mostly used in cases where the
main thread is only required to spawn threads and leave the threads to do their job
pthread_join
will suspend execution of the thread that has called it unless the target thread terminates
This is useful in cases when you want to wait for thread/s to terminate before further
processing in main thread.
pthread_exit
终止调用线程时pthread_join
暂停调用线程的执行,直到目标线程完成执行为止。在开放组文档中对它们进行了详细的详细解释:
pthread_exit
terminates the calling thread whilepthread_join
suspends execution of calling thread until target threads completes execution.They are pretty much well explained in detail in the open group documentation:
两种方法都确保您的 Process 在所有线程结束之前都不会结束。
JOIN方法具有您的
main
函数的线程明确等待要“加入”的所有线程。pthread_exit
方法以受控方式终止您的MAIN
函数和线程。main
具有以下特殊性:结束main
否则将终止您的整个过程,包括所有其他线程。为此,您必须确保任何线程都不使用其中声明的本地变量
main
函数。该方法的优点是您的main
不必知道您过程中启动的所有线程,例如,其他线程本身就创建了main
的新线程什么都不知道。Both methods ensure that your process doesn't end before all of your threads have ended.
The join method has your thread of the
main
function explicitly wait for all threads that are to be "joined".The
pthread_exit
method terminates yourmain
function and thread in a controlled way.main
has the particularity that endingmain
otherwise would be terminating your whole process including all other threads.For this to work, you have to be sure that none of your threads is using local variables that are declared inside them
main
function. The advantage of that method is that yourmain
doesn't have to know all threads that have been started in your process, e.g because other threads have themselves created new threads thatmain
doesn't know anything about.PTHREAD_EXIT()API
如已经注释,用于调用线程终止。
打电话给该功能后,开始了复杂的清理机构。
完成线程后,线程将终止。
当对返回()例程的调用发生在PTHREAD_CREATE()创建的线程中时,PTHREAD_EXIT()API也被隐式称为。
实际上,返回()的调用和呼叫pthread_exit()具有相同的影响,是从pthread_create()创建的线程中调用的。
区分主()函数启动时隐含创建的初始线程以及由pthread_create()创建的线程。
从main()函数呼叫返回()例程隐式调用exit()系统调用,整个过程终止。
没有线程清理机制。
从main()函数对PTHREAD_EXIT()调用呼叫会导致清理机制启动并完成工作时,初始线程终止。
当pthread_exit()从main()函数调用PTHREAD实现时,整个过程(以及其他线程)发生了什么。
例如,在IBM OS/400实现上,当PTHREAD_EXIT()从main()函数调用PTHREAD_EXIT()时,整个过程终止了。
其他系统的行为可能会有所不同。
在大多数现代Linux机器上,从初始线程调用PTHREAD_EXIT()调用直到所有线程终止之前,都不会终止整个过程。
如果要编写便携式应用程序。
pthread_join()API
是一种等待线程终止的方便方法。
您可以编写自己的功能,该功能等待线程终止,也许更适合您的应用程序,而不是使用pthread_join()。
例如,它可以是基于等待条件变量的函数。
我建议阅读 David R. Butenhof的一本书“与Posix线程的编程”。
它很好地解释了讨论的主题(以及更复杂的事物)(尽管某些实现细节,例如主要功能中的pthread_exit用法,并不总是在书中反映出来)。
The pthread_exit() API
as has been already remarked, is used for the calling thread termination.
After a call to that function a complicating clean up mechanism is started.
When it completes the thread is terminated.
The pthread_exit() API is also called implicitly when a call to the return() routine occurs in a thread created by pthread_create().
Actually, a call to return() and a call to pthread_exit() have the same impact, being called from a thread created by pthread_create().
It is very important to distinguish the initial thread, implicitly created when the main() function starts, and threads created by pthread_create().
A call to the return() routine from the main() function implicitly invokes the exit() system call and the entire process terminates.
No thread clean up mechanism is started.
A call to the pthread_exit() from the main() function causes the clean up mechanism to start and when it finishes its work the initial thread terminates.
What happens to the entire process (and to other threads) when pthread_exit() is called from the main() function depends on the PTHREAD implementation.
For example, on IBM OS/400 implementation the entire process is terminated, including other threads, when pthread_exit() is called from the main() function.
Other systems may behave differently.
On most modern Linux machines a call to pthread_exit() from the initial thread does not terminate the entire process until all threads termination.
Be careful using pthread_exit() from main(), if you want to write a portable application.
The pthread_join() API
is a convenient way to wait for a thread termination.
You may write your own function that waits for a thread termination, perhaps more suitable to your application, instead of using pthread_join().
For example, it can be a function based on waiting on conditional variables.
I would recommend for reading a book of David R. Butenhof “Programming with POSIX Threads”.
It explains the discussed topics (and more complicated things) very well (although some implementation details, such as pthread_exit usage in the main function, not always reflected in the book).
您不需要任何电话
pthread_exit(3)代码>
在您的特定代码中。
通常,
main
线程应不是调用pthread_exit
,但通常应调用pthread_join(3)
to 等待等待以完成其他一些线程。在您的
printhello
函数中,您无需调用pthread_exit
,因为它是在返回之后隐含的。因此,您的代码应该是:
You don't need any calls to
pthread_exit(3)
in your particular code.In general, the
main
thread should not callpthread_exit
, but should often callpthread_join(3)
to wait for some other thread to finish.In your
PrintHello
function, you don't need to callpthread_exit
because it is implicit after returning from it.So your code should rather be:
PTHREAD_EXIT()
将终止调用线程并退出(但是,如果调用线程使用的资源不从主线程分离为操作系统。)pthrade> pthrade_join()将等待或阻止调用线程,直到目标线程未终止。
简单地说,它将等待退出目标线程。
在您的代码中,如果将睡眠(或延迟)放入
printhello
函数之前pthread_exit()
,则可以退出主线程并终止完整过程,尽管您的> printhello
函数未完成,它将终止。如果您在呼叫pthread_exit()
之前使用pthrade_join()
函数,则从main中,它将阻止主线程并等待完成您的调用线程(printhello
)。pthread_exit()
will terminate the calling thread and exit from that(but resources used by calling thread is not released to operating system if it is not detached from main thread.)pthrade_join()
will wait or block the calling thread until target thread is not terminated.In simple word it will wait for to exit the target thread.
In your code, if you put sleep(or delay) in
PrintHello
function beforepthread_exit()
, then main thread may be exit and terminate full process, Although yourPrintHello
function is not completed it will terminate. If you usepthrade_join()
function in main before callingpthread_exit()
from main it will block main thread and wait to complete your calling thread (PrintHello
).