线程创建等待及退出
1.Linux上线程开发API概要
多线程开发在 Linux 平台上已经有成熟的 pthread 库支持。其涉及的多线程开发的最基本概念主要包含三点:线程,互斥锁,条件。其中,线程操作又分线程的创建,退出,等待 3 种。互斥锁则包括 4 种操作,分别是创建,销毁,加锁和解锁。条件操作有 5 种操作:创建,销毁,触发,广播和等待。其他的一些线程扩展概念,如信号灯等,都可以通过上面的三个基本元素的基本操作封装出来。详细请见下表:
2.与线程自身相关API
线程创建:
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号在这里插入代码片
当pthread_create成功返回时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于定制各种不同的线程属性,暂可以把它设置为NULL,以创建默认属性的线程。
新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg参数传入。
线程退出:
单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:
1)线程只是从启动例程中返回,返回值是线程的退出码。
2)线程可以被同一进程中的其他线程取消。
3)线程调用pthread_exit:
#include <pthread.h>
int pthread_exit(void *rval_ptr);
rval_ptr是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用pthread_join函数访问到这个指针。
线程等待:
#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
调用这个函数的线程将一直阻塞,直到指定的线程调用pthread_exit、从启动例程中返回或者被取消。如果例程只是从它的启动例程返回i,rval_ptr将包含返回码。如果线程被取消,由rval_ptr指定的内存单元就置为PTHREAD_CANCELED。
可以通过调用pthread_join自动把线程置于分离状态,这样资源就可以恢复。如果线程已经处于分离状态,pthread_join调用就会失败,返回EINVAL。
如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并不获得线程的终止状态。
综合使用例程:
代码:
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号----创建线程
void *func1(void*arg)//参数3:调用无类型指针API
{
static int ret=10;//使函数结束,内存还在
static char *p = "t1 is run out";
printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
//pthread_self():返回自身线程id,为pthread_t类型
printf("t1:param is %d:\n",*((int*)arg));//转化为int*,再取值
//pthread_exit((void *)&ret);
pthread_exit((void *)p);
}
int main()
{
int ret;//返回值
pthread_t t1;
int param=100;//参数4:调用时:将int*转化为void*.100:随便给的数
//int *pret=NULL;
char *pret1=NULL;
ret=pthread_create(&t1,NULL,func1,(void*)¶m);
//参数1:指针指向t1,NULL:线程属性,参数3:启动线程调用的函数,参数4:打印的值
if(ret==0)
{
printf("main函数创建线程t1成功\n");
}
printf("main:%ld\n",(unsigned long)pthread_self());
//pthread_join(t1,NULL);//等待线程,主线程执行完不收回,等待子线程
//pthread_join(t1,(void **)&pret);//等待线程,pret不指向null,指向ret
pthread_join(t1,(void **)&pret1);//等待线程,pret不指向null,指向ret
//printf("main:t1 quit:%d\n",*pret);
printf("main:t1 quit:%s\n",pret1);
return 0;
}
执行结果:
dazai@dazai:~$ gedit demo1.c
dazai@dazai:~$ gcc demo1.c -lpthread
dazai@dazai:~$ ./a.out
main函数创建线程t1成功
t1:-1210954944 thread is create
t1:param is 100:
main:-1210951936
main:t1 quit:t1 is run out