如何高效放鸽子——线程的创建、等待和销毁
前文再续,书接上一回
今天我们将会采访一位放鸽子高手,探讨如何高效地放放鸽子
记者:您好,真是百闻不如一见,没想到传说中的鸽王相貌平平却有如此大的能耐
鸽王:过奖过奖
记者:作为Linux王国中放鸽子时间最长、多鸽运动的佼佼者,您有什么可以分享给大家的秘籍吗!
鸽王:哪有什么秘诀,最多是一些小经验而已
记者:您谦虚了
鸽王:哪有,我就是在别人放一只鸽子的时候放更多鸽子而已
记者:那您是怎么放更多鸽子的呢?
鸽王:我当然是使用了线程了,线程能让我们在同一个时间里面放更多的鸽子
记者:那我们为什么要创建线程而不是另起一个进程呢?
鸽王:这个问题简单,我打个比方,我们要放两只鸽子去飞鸽传书,现在我们有两种选择,一向鸽子一厂和鸽子二厂各买一只鸽子,二向同一个鸽子厂买两只鸽子,你觉得有什么区别?
记者:都是两个鸽子,应该没什么区别吧?
鸽王:区别可大了,因为进程的开销比线程的开销大,不同鸽子厂的鸽子要吃的饲料是不一样的,如果我分别养着不同鸽子厂的鸽子,我就要买两种不同的饲料,从短期来看我所花费的钱就多了;而如果我只向其中一个鸽子厂买两只鸽子,那我只需要买一种饲料,这样我的花费钱就少了
记者:那应该怎样放多个鸽子呢?
鸽王:那就要创建线程了
创建线程所用到的函数
头文件 | #include<pthread.h> |
函数原型 | int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(*void), void *arg) |
传入的参数 | thread:当线程创建成功时,返回新线程的ID |
attr:线程属性,NULL为默认属性 | |
start_routine:线程创建后调用的函数,也称为线程函数 | |
arg:传递给线程函数的参数 | |
返回值 | 成功:返回0 |
失败:返回-1 | |
备注 | 该函数用于创建新线程 |
pthread_t tid;
pthread_a = pthread_create(&tid, NULL, (void *)thread_a, NULL);
if(pthread_a != 0){
perror("a线程创建错误");
exit(1);
}
鸽王:每创建一个进程你就可以多放一个鸽子了。
一段时间后
记者:鸽子飞了好久都没有回来,要不我们先去附近吃个饭
鸽王:当然可以,不过我们提前离开前的话可能会收不到鸽子带回来的信息,为了避免鸽子以为我们不会回来找它,在我们就得要在这里放上一个标识,表示我们还在附近等它,直到它回来我们才彻底离开。
等待线程所用到的函数
头文件 | #include<pthread.h> |
函数原型 | int pthread_join(pthread_t thread, void **retval) |
传入的参数 | thread:等待线程的ID |
retval:线程没有返回值时为NULL;参数不为NULL时,为被等待线程结束时pthread_exit的retval | |
返回值 | 成功:返回0 |
失败:返回-1 | |
备注 | 该函数用于线程等待,调用pthread_join函数的线程将会被挂起,等到线程ID为thread的线程结束 |
pthread_join(tid,NULL);
鸽王:这样子直到子线程结束任务之前,主线程就会处于挂起状态,只有子线程结束后,才能主线程才能继续运行下去
过了大概一个小时后,空中下起倾盆大雨
记者:我看了天气预报说全省都会下大暴雨,这样子鸽子会不会出事
鸽王:放心,我跟鸽子对过暗号,一旦发生特殊情况就往回飞,所以不用担心
线程结束所用到的函数
头文件 | #include<pthread.h> |
函数原型 | int pthread_exit(void *retval) |
传入的参数 | retval:如果 pthread_join 中的第二个参数retval不为空时, 这个值将被传递给pthread_join的retval |
返回值 | 成功:返回0 |
失败:返回-1 | |
备注 | 该函数用于结束线程,如果 pthread_join 中的第二个参数retval不为空时, 这个值将被传递给pthread_join的retval |
pthread_exit()使用方法
void *thread_a(){
int i;
for(i=0;i<10;i++){
printf("%d\n",i);
}
pthread_exit(NULL);
}
int main(){
int pthread_a;
pthread_t tid;
pthread_a = pthread_create(&tid, NULL, (void *)thread_a, NULL);
if(pthread_a != 0){
perror("a线程创建错误");
exit(1);
}
pthread_join(tid,NULL);//等待线程结束
return 0;
}
记者:感谢今天鸽王给我们传授了如何更有效率地放鸽子,下一次我们就去采访放鸽台的工作人员