1.线程的实现方式
1.用户级线程
开销小,用户空间就可以创建多个。缺点是:内核无法感知用户级多个线程的存在,把其当作只有一个线程,所以只会提供一个处理器。
2.内核级线程
相对于用户级开销稍微大一点,可以利用多个处理器。
3.组合级线程
在不同平台Linux 中线程的实现:
Linux 实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。Linux 把所有的线程都当做进程来实现。内核并没有准备特别的调度算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个与其他进程共享某些资源的进程。每个线程都拥有唯一隶属于自己的 task_struct,所以在内核中,它看起来就像是一个普通的进程(只是线程和其他一些进程共享某些资源,如地址空间)。
2.线程的使用
2.1线程库的接口—pthread函数
1)pthread_create
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
pthread_create()创建一个新的线程,类似于创建新进程的fork函数
参数一:pthread_t *thread:指向一个pthread_t类型数据的指针,线程被创建时,这个指针指向的变量中会被写入一个标识符,我们用该标识符引用新线程;
thread:接收创建的新线程的ID,根据不同的ID名,对相应的线程做管理
参数二:const pthread_attr_t *attr
attr: 指定线程的属性,一般不设置特殊属性,设置该参数为NULL;
参数三:void *(*start_routine) (void *):参数为void类型指针,返回值也为指向void的指针的函数地址。告知新线程从这个函数指针指向的位置开始执行。
start_routine: 线程将要启动的指定线程函数
参数四:void *arg:给线程函数传递的参数指针
arg: 给线程函数传递的参数//成功返回 0, 失败返回错误代码
2)pthread_join
int pthread_join(pthread_t thread, void **retval);
pthread_join()等待 thread 指定的线程退出,线程未退出时,该方法阻塞。等价于进程中用于收集子进程退出信息的wait函数。
参数一:pthread_t thread:指定将要等待的线程(此处用pthread_t变量名),
参数二:void **retval:是一个指针,它指向另一个指针,后者指向线程的退出信息。//成功返回 0, 失败返回错误代码
3)pthread_exit
int pthread_exit(void *retval);
pthread_exit()线程通过调用此函数终止执行。等价于进程结束时调用exit函数退出
参数:void *retval:指向线程退出信息的指针或者说是线程退出时返回指向某个对象的指针,该对象不能是局部对象,因为此函数结束后,该局部变量就不存在了,会引起程序泄漏。