在操作系统中并没有提供创建线程的系统调用接口(这也是为什么有人说Linux中没有线程的原因),而是大佬们封装的一套库函数实现线程控制的各个操作
在程序中程序员通过库函数创建线程,实际上创建了一个用户态线程,并且伴随在内核中创建了一个轻量级PCB实现线程的调用
POSIX线程库:
与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以
“pthread_”
打头的
要使用这些函数库,要通过引入头文
<pthread.h>
链接这些线程函数库时要使用编译器命令的
“-lpthread”
选项
线程创建:创建一个执行流,能够独立完成某个任务
功能:创建一个新的线程
int pthread_create(pthread_t *tid, pthread_attr_t *attr, void*(pthread_routine)(void *arg), void *arg);
参数:
thread:返回线程ID
attr:设置线程的属性,attr为NULL表示使用默认属性
start_routine:是个函数地址,线程启动后要执行的函数
arg:传给线程启动函数的参数
返回值:成功返回0;失败返回错误码
pthread_create函数会产生一个线程id,存放在第一个参数指向的地址中。该线程id和前面说的线程id不是一回事
前面说的线程id属于进程调度的范畴,因为线程是轻量级进程,是操作系统调度的最小单位,所以需要一个数值来唯一表示该线程。
pthread_create函数第一个参数所指向的虚拟内存单元,该内存单元的地址就是新创建线程的线程ID,属于NPTL线程库的范畴。线程库的后续操作就是根据线程的ID来操作线程的
线程库NPTL提供了pthreda_self函数,可以获得线程自身的id
pthread_t pthread_self(void);
#inlcude <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
void *rout(void *arg)
{
int i;
for(; ;)
printf("i am thread\n");
sleep(1);
}
int main()
{
pthread_t tid;
int ret;
if(ret = pthread_create(&tid,NULL,rout,NULL)!= 0)
{
fprintf(stderr,"pthread_create: %s\n",strerror(ret));
exit(EXIT_FAILURE);
}
int i;
for( ; ; ){
pprinft("i am main thread\n");
}
sleep(1);
return 0;
}