APUE-线程及其属性:pthread_join与pthread_detach

来源:互联网 发布:加拿大gpa算法美国 编辑:程序博客网 时间:2024/05/17 23:12

pthread_join使一个线程等待另一个线程结束。

代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。

int pthread_join(pthread_t thread, void **value_ptr); 

返回值:若成功则返回0,若出错则为非零。

thread:等待退出线程的线程号。

value_ptr:退出线程的返回值。

   (1)在线程的属性设置为joinable之后,可以调用pthread_detach()使之成为detached。(属性的设置在线程创建之前)                   

(2)如果线程已经调用pthread_join()后,则再调用pthread_detach()则不会有任何效果。

(3)若是在调用pthread_detach()之后,则不能再在线程的属性设置为joinable或者再调用pthread_join();

int pthread_detach(pthread_t tid);

 返回值:若成功则返回0,若出错则为非零。       

pthread_detach用于分离可结合线程tid。线程能够通过以pthread_self()为参数的pthread_detach调用来分离它们自己。如果一个可结合线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process(僵死进程),即还有一部分资源没有被回收,所以创建线程者应该调用pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源。

 由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此。例如,在Web服务器中当主线程为每个新来的连接请求创建一个子线程进行处理的时候,主线程并不希望因为调用pthread_join而阻塞(因为还要继续处理之后到来的连接请求),这时可以在

子线程中加入代码: pthread_detach(pthread_self())

或者父线程调用: pthread_detach(thread_id)(非阻塞,可立即返回)

这将该子线程的状态设置为分离的(detached),如此一来,该线程运行结束后会自动释放所有资源。

 最后说一下线程的本质。其实在Linux中,新建的线程并不是在原先的进程中,而是系统通过 一个系统调用clone()。该系统copy了一个和原先进程完全一样的进程,并在这个进程中执行线程函数。不过这个copy过程和fork不一样。 copy后的进程和原先的进程共享了所有的变量,运行环境。这样,原先进程中的变量变动在copy后的进程中便能体现出来。


注:

通过创建线程,线程将会执行一个线程函数,该线程格式必须按照下面来声明:

       void * Thread_Function(void *)

创建线程的函数如下:

       int pthread_create(pthread_t *restrict thread,

              const pthread_attr_t *restrict attr,

              void *(*start_routine)(void*), void *restrict arg);

下面说明一下各个参数的含义:

thread:所创建的线程号。

attr:所创建的线程属性,这个将在后面详细说明。

start_routine:即将运行的线程函数。

art:传递给线程函数的参数。

如果想传递参数给线程函数,可以通过其参数arg,其类型是void *。如果你需要传递多个参数的话,可以考虑将这些参数组成一个结构体来传递。另外,由于类型是void *,所以你的参数不可以被提前释放掉。(可以使用全局结构或者在主线程调用malloc()函数)


0 0