linux库函数中能使用线程吗,Linux下多线程的实现(基于pthread库)

Linux内核在2.2版本中引入了相似线程的机制。Linux提供的vfork函数能够建立线程,此外Linux还提供了clone来建立一个线程,经过共享原来调用进程的地址空间,clone能像独立线程同样工做。Linux内核的独特,容许共享地址空间,clone建立的进程指向了父进程的数据结构,从而完成了父子进程共享内存和其余资源。clone的参数能够设置父子进程共享哪些资源,不共享哪些资源。实质上Linux内核并无线程这个概念,或者说Linux不区分进程和线程。Linux喜欢称他们为任务。除了clone进程之外,Linux并不支持多线程,独立数据结构或内核子程序。可是POSIX标准提供了Pthread接口来实现用户级多线程编程。编程

POSIX下开发多线程主要依赖的就是Pthread。使用它须要包含头文件#include。由于这个库在Pthread之中,在编译的时候须要加上参数:-lpthread.多线程

线程的建立

pthread_create()函数用于建立一个线程。他的函数原型以下函数

extern int pthread_create (pthread_t *__restrict __newthread,

const pthread_attr_t *__restrict __attr,

void *(*__start_routine) (void *),

void *__restrict __arg);

__newthread是要建立线程的线程ID指针

__restrict __attr是建立线程时的属性

void *(*__start_routine) (void *)线程函数的入口地址

__arg是传递给线程函数的参数

函数返回值:调用成功后返回0,不然,建立线程失败。从第三个参数,也就是线程函数入口地址。从这儿能够知道线程函数的书写格式应该是具备void *类型的返回值,另外参数也是void *类型的。测试

线程建立之后之后的调度仍旧是不肯定的。实际上,在Linux下线程ID是使用一个无符号长整型来表示的。url

等待线程结束

pthread_join()函数用于等待线程结束,回收资源。相似于进程等待仍是waitpid。spa

函数原型:int pthread_join(thread_t tid,void **status);.net

函数功能:tid是指定的要等待的线程ID,指定的线程必须位于当前进程之中,并且不能是分离线程。status指向线程退出状态的指针。线程

函数返回值:成功返回0,不然表示出现错误。指针

pthread_join只能适用于非分离的线程,所以若是没有必要等待线程终止,则应该将该线程分离。若是线程已经处于分离状态,那么调用失败。

线程终止

一个线程的终止有3种状况:

线程调用了pthread_exit()函数退出

线程被同一进程的其余线程取消

线程从执行函数返回,返回值是线程退出码

有一个特殊情形是main所在的线程,咱们称之为“初始线程”。从mian返回的时候,整个进程都被终止了,所以该进程全部的线程也被终止。还有就是在任意线程内调用exit函数会让该线程所在的进程整个退出。主动退出线程的时候必定要使用pthread_exit函数,而不是exit。pthread_exit在退出线程之后并不会释放资源,而是须要pthread_join函数来释放。当主线程调用这个pthread_exit函数仅仅只是终止主线程,其余线程仍将继续存在。

函数原型:void pthread_exit(void *retval)

参数retval能够经过pthread_join()来访问到这个指针。若是线程成功返回到启动它的线程,那么retval就会包含返回码,若是线程被取消,retval就会指向包含内容为PTHREAD_CANCELED的单元。若是对线程结束的返回值并不感兴趣,那么将retval设置为NULL便可。

一个测试程序以下:

#include

#include

#include

#include

void *fun(void *arg) //线程函数

{

printf("%s\n",(char *)arg); //打印传递过来的参数

printf("thread\n");

pthread_exit(NULL); //调用pthread_exit函数退出线程

printf("test!\n");

}

int main()

{

pthread_t id;

int t = pthread_create(&id,NULL,fun,"argue");

if(0 != t)

{

perror("pthread_create fail");

exit(errno);

}

printf("main\n");

pthread_join(id,NULL); //等待线程执行返回

return 0;

}

执行结果以下:

cc3265f22137e4ca2c6e8700d54b27c8.png

在编译源代码的时候须要连接pthread库,编译选项须要加上 -lpthread。

运行结果是正确的,主线程等待子线程结束,在子线程中调用了的pthread_exit函数结束了子线程,因此没有打印test!。

下面这个例子是对上面的这个例子一点小小的变化,能够经过pthread_join()来获取pthread_exit()的返回值。

#include

#include

#include

#include

void *fun(void *arg) //线程函数

{

printf("%s\n",(char *)arg); //打印传递过来的参数

printf("thread\n");

pthread_exit((void *)3); //调用pthread_exit函数退出线程,并设置退出码

printf("test!\n"); //不会执行到这里

}

int main()

{

pthread_t id;

void *status;

int t = pthread_create(&id,NULL,fun,"arguement");

if(0 != t)

{

perror("pthread_create fail");

exit(errno);

}

printf("main\n");

pthread_join(id,&status); //等待线程执行返回

printf("%ld\n",(long)status); //打印线程退出码

return 0;

}

367156045b19a2063d2fd55e58b3667c.png

线程取消

前面说过线程的终止包含3种状况,其中有一种就是线程被取消了。线程能够经过pthread_cancle来请求取消同一进程内的其余线程。

函数原型:int pthread_cancel(pthread_t thread);

该函数只是去请求取消,而不是命令取消。所以,默认情形下,他会使得线程取消。可是线程能够选择忽略或者控制如何取消。

本文同步分享在 博客“zy010101”(CSDN)。

若有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值