1.Linux线程的发展
早在LINUX2.2内核中。并不存在真正意义上的线程,当时Linux中常用的线程pthread实际上是通过进程来模拟的,也就是同过fork来创建“轻”进程,并且这种轻进程的线程也有个数的限制:最多只能有4096和此类线程同时运行。
2.4内核消除了个数上的限制,并且允许在系统运行中动态的调整进程数的上限,当时采用的是Linux Thread 线程库,它对应的线程模型是“一对一”,而线程的管理是在内核为的函数库中实现,这种线程得到了广泛的应用。但是它不与POSIX兼容。另外还有许多诸如信号处理,进程ID等方面的问题没有完全解决。
相似新的2.6内核中,进程调度通过重新的编写,删除了以前版本中的效率不高的算法,内核框架页也被重新编写。开始使用NPTL(Native POSIX Thread Library)线程库,这个线程库有以下几个目标: POSIX兼容,都处理结果和应用,底启动开销,低链接开销,与Linux Thread应用的二进制兼容,软硬件的可扩展能力,与C++集成等。 这一切是2.6的内核多线程机制更加完备。
2.Linux 线程的实现
Linux线程的基本操作
这里主要讲的线程以及相关操作都是用户空间的线程操作,在Linux中,一般pthread线程库是一套通用的线程库,是由POSIX提出的,因此具有很好的可移植性。
2.1 线程的创建: 创建线程通常使用的函数是pthread_create.
2.2 线程的退出:
1) 在线程创建以后,就开始运行相关的线程函数,在该函数运行完之后,该线程也就退出了。这是线程退出的一种方法: 运行完毕,自动退出;
2) 调用pthread_exit函数主动退出;
3) 进程终止函数exit函数,一旦结束了进程,那么此进程中所有线程都将无条件终止。
一个注意点:在默认线程属性下,如果一个进程有很多线程在同时运行,一个线程在退出以后,当前线程所占用的资源并不会随着线程的终止而得到释放。因为所有处在一个进程中的线程共享资源。
线程中还有一个常用函数:pthread_join函数可以用于将当前线程挂起,等待其他线程结束。实际上,这个函数是就是一个线程阻塞函数,调用它的函数将一直等待到被等待的线程结束为止。当函数返回时,被等待线程的资源就被回收。
pthread_create 函数:
所需文件头: |
#include <pthread.h>
|
函数原型:
|
int pthread_create((pthread_t*thread,pthread_attr_r*attr,void*(*start_routine) (void*),void *arg))
|
函数传入值:
|
thread:线程标识符
|
|
attr: 线程属性设置 null表示采用默认
|
|
start_roitine : 线程函数的启示地址
|
|
arg :传递给start_routine的参数
|
函数返回值:
|
成功:0 出错:-1
|
pthread_exit函数
所需文件头: |
#include <pthread.h>
|
函数原型:
|
Void pthread_exit(void *retval)
|
函数传入值:
|
retval:调用者线程的返回值,可由其他函数如pthread_join来检索获取。
|
pthread_join函数
所需文件头: |
#include <pthread.h>
|
函数原型:
|
int pthread_join ((pthread_t th,void **thread_return))
|
函数传入值:
|
th: 等待线程的标识符 thread_return:用户定义的指针,用来存储被等待线程的返回值(不为NULL时)
|
函数返回值:
|
成功:0
|
|
出错:-1
|
取消一个线程
有时候,我们想让一个线程 能够请求另外一个线程结束,就像给它发送一个信号似的。用线程程是可以完成这一操作的,而与单处理经,线程在被要求结束执行的时候还有一种改变其行为的办法。
我们来看看要求一个线程结束执行的函数
所需文件头: |
#include <pthread.h>
|
函数原型:
|
int pthread_cancel(pthread_t thread);
|
函数传入值:
|
thread:线程的标识符
|
函数返回值:
|
成功:0
|
|
出错:-1
|
这个定义很明白,给定一个线程标识符,我们就能要求取消它。但在取消线形程请求的接收端,事情会稍微复杂一些,好在也不是太复杂。线形程可以用pthread_setcancelstate设置自己的取消状态,下面是这个函数的定义:
所需文件头: |
#include <pthrea.h>
|
函数原型:
|
int pthread_setcancelstate(int state,int *oldstate);
|
函数传入值:
|
state:可以是PTHREAD_CANCEL_ENABLE,这个值允许线程接收取消请求;还可以是PTHREAD_CANCEL_DISABLE,它的作用是屏幕它们。 线程以前的取消状态可以用oldstate指针检索出来。如果没兴趣可以传一个NULL进去。
|
函数返回值:
|
成功:0
|
|
出错:-1
|
如果取消请求被接受了,线程会进入第二个控制层次----用pthread_setcanceltype设置取消类型。
所需文件头: |
#include <pthrea.h>
|
函数原型:
|
int pthread_setcanceltype(int type,int *oldstate);
|
函数传入值:
|
type:可以有两种取值,一个是PTHREAD_CANCEL_ASYNCHORONOUS,接收到取消请求之后立刻采取行动;另一个是PTHREAD_CANCEL_DEFERRED,在接收到取消请求之后、采取实际行动之前,先执行以下几个函数之一:pthread_join、pthread_cond_wait、pthread_cond_timewait、pthread_testcancel、sem_wait或sigwait。
|
函数返回值:
|
成功:0
|
|
出错:-1
|
稍微注意一点就是在android-ndk-r3 里是不支持int pthread_cancel(pthread_t thread); 所以想强制退出线程似乎没有更好的办法。
=================================================================================
linux多线程pthread的函数声明在<pthread.h>中,因此在使用该函数时,需要把该头文件引入。
线程的创建
1、创建
int pthread_create( pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(* func) (void *), void *restrict arg );
attr: 线程属性包括:优先级、初始栈大小,是否应该成为一个守护线程。
缺省设置,NULL
tidp是要创建的线程,创建成功后tipd为先线程的id
void *(* func) (void *)是一个函数指针,该函数指针的类型为void* (*)(void *)
是一个参数为void *,返回值也为void *的函数类型。它的一个简单的例子如下
void *thread_handler(void *arg)
{
return NULL;
}
void *restrict arg
中的arg是void *(* func) (void *)函数指针的参数。
补充:函数声明中多次出现了restrict,其实这是用于CPU对函数的优化使用的,restrict的使用,由程序员保证使用restrict标志的参数间不会有内存重叠。
获取线程自身的id
pthread_t pthread_self(void);
等待给定线程终止
int pthread_join( pthread_t tid, void **status);
statues返回等待线程的返回值
单个线程有三种退出方式
1.线程从启动例程中返回(return方式),返回值是现成的退出码
2.线程被同一进程内的其他线程取消
3.线程调用pthread_exit退出。void pthread_exit(void *rval_ptr)
线程清理处理程序
void pthread_clean_push(void (*rtn)(void *),void *arg)
void pthread_clean_pop(iny excute)
清理函数rtn的调用顺序是由pthread_clean_push函数安排的。
它在下列几种情况下执行:
1.调用pthread_exit时
2.响应取消请求时
3.用非零execute参数调用pthread_clean_pop时
如果execute参数为0,清理函数将不被调用。无论何种情况,pthread_clean_pop都将删除上次pthread_clean_push建立的清理处理程序。
如果线程使用return从例程返回,那么pthread_clean_push建立的清理处理程序不会被执行。
linux thread与fork的对比
进程原语 |
线程原语 |
描述 |
fork |
pthread_create |
创建新的控制流 |
exit |
pthread_exit |
从现有的控制流退出 |
waitpid |
pthread_join |
从控制流中得到退出状态 |
atexit |
pthread_clean_push |
注册在退出控制流时执行的函数 |
getpid |
pthread_self |
获得控制流ID |
abort |
pthread_cancel |
请求控制流的非正常退出 |
=================================================================================
分享到:
相关推荐
pthread多线程求pi,linux多线程pthread,C,C++源码
pthread多线程求pi,linux多线程pthread,C,C++源码.rar
并行计算pthread多线程求pi的三种方法,编译后在命令行后输入线程数以及计算规模n运行
linux 多线程编程 pthread 中文文档 已经添加目录
Linux下使用pthread库编写的简单的多线程程序,在调用线程时绑定了内核
一个示例程序,演示在linux环境下如何使用pthread实现多线程的使用和控制。
Linux 多线程 聊天室 C++,用eclipse即可。linux多线程在编译时需要添加一些pthread库,编译命令需要加-Ip
linux下多线程实现矩阵乘法,可以对操作系统的线程有更多理解
Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。顺便说一下,Linux下pthread的实现是通过系统调用clone()来实现的。...
linux多线程程序实验,用不同线程完成一个矩阵乘法,以及子进程计算斐波那契数列,父进程输出结果
Linux多线程编程手册,详述了Solaris 线程 API 和 pthread API
linux多线程编程.ppt 对于了解大概很有用处.是linux多线程学习路线的指南! 倡导免费下载!鄙视要资源分的!
Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别,不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断。本文中我们从 5 个方面总结出 Linux 多...
Linux下多线程编程-Pthread与Semaphore的使用.doc
Linux下的pthread全面介绍 包括条件变量与信号量
linux c语言 聊天室 多线程 pthread
5本Linux多线程合集: 多线程编程指南.pdf, Linux多线程编程手册.pdf, 多线程编程技术, posix pthread API, 专家级多线程技术.Eng.pdf
代码目的是比较write和printf多路写性能。首先fork生成子进程,并且在子进程中重定向标准输出;然后在父子进程中各创建10个线程分别利用printf和write进行写操作;最后通过返回值比较两者性能。