Linux多线程编程快速入门

2019-10-10 16:07:50于海丽

返回值:

成功时,返回0 
错误时,返回正数错误码

当线程X连接线程Y时,如果线程Y仍在运行,则线程X会阻塞直到线程Y终止;如果线程Y在被连接之前已经终止了,那么线程X的连接调用会立即返回。

连接线程其实还有另外一层意义,一个线程终止后,如果没有人对它进行连接,那么该终止线程占用的资源,系统将无法回收,而该终止线程也会成为僵尸线程。因此,当我们去连接某个线程时,其实也是在告诉系统该终止线程的资源可以回收了。

注意:对于一个已经被连接过的线程再次执行连接操作, 将会导致无法预知的行为!

5.2 线程的分离

有时我们并不在乎某个线程是不是已经终止了,我们只是希望如果某个线程终止了,系统能自动回收掉该终止线程所占用的资源。pthread_detach函数为我们提供了这个功能,该功能称为线程的分离:

#include <pthread.h>
int pthread_detach(pthread_t thread);

默认情况下,一个线程终止了,是需要在被连接后系统才能回收其占有的资源的。如果我们调用pthread_detach函数去分离某个线程,那么该线程终止后系统将自动回收其资源。

/*
* 文件名: thread_sample1.c
* 描述:演示线程基本操作
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

/*子线程1入口函数*/
void *thread_routine1(void *arg)
{
 fprintf(stdout, "thread1: hello world!n");
 sleep(1);
 /*子线程1在此退出*/
 return NULL;
}

/*子线程2入口函数*/
void *thread_routine2(void *arg)
{

 fprintf(stdout, "thread2: I'm running...n");
 pthread_t main_thread = (pthread_t)arg;

 /*分离自我,不能再被连接*/
 pthread_detach(pthread_self());

 /*判断主线程ID与子线程2ID是否相等*/
 if (!pthread_equal(main_thread, pthread_self())) {
  fprintf(stdout, "thread2: main thread id is not equal thread2n");
 }

 /*等待主线程终止*/
 pthread_join(main_thread, NULL);
 fprintf(stdout, "thread2: main thread exit!n");

 fprintf(stdout, "thread2: exit!n");
 fprintf(stdout, "thread2: process exit!n");
 /*子线程2在此终止,进程退出*/
 pthread_exit(NULL);
}

int main(int argc, char *argv[])
{

 /*创建子线程1*/
 pthread_t t1;
 if (pthread_create(&t1, NULL, thread_routine1, NULL)!=0) {
  fprintf(stderr, "create thread fail.n");
  exit(-1);
 }
 /*等待子线程1终止*/
 pthread_join(t1, NULL);
 fprintf(stdout, "main thread: thread1 terminated!nn");

 /*创建子线程2,并将主线程ID传递给子线程2*/
 pthread_t t2;
 if (pthread_create(&t2, NULL, thread_routine2, (void *)pthread_self())!=0) {
  fprintf(stderr, "create thread fail.n");
  exit(-1);
 }

 fprintf(stdout, "main thread: sleeping...n");
 sleep(3);
 /*主线程使用pthread_exit函数终止,进程继续存在*/
 fprintf(stdout, "main thread: exit!n");
 pthread_exit(NULL); 

 fprintf(stdout, "main thread: never reach here!n");
 return 0;
}