一 Linux--多线程( 二 )


Linux下的进程和线程进程: 承担分配系统资源的实体线程: CPU调度的基本单位注意: 进程之间具有很强的独立性 , 但是线程之间是会互相影响的
线程共享一部分进程数据 , 也有自己独有的一部分数据:(每个线程都有属于自己的PCB)

  • 线程ID
  • 一组寄存器(记录上下文信息 , 任务状态段)
  • 独立的栈空间(用户空间栈)
  • 信号屏蔽字
  • 调度优先级
  • errno(错误码)
  • 处理器现场和栈指针(内核栈)
进程的多个线程共享同一地址空间 , 因此Text Segment、Data Segment都是共享的 。如果定义一个函数,在各线程中都可以调用 , 如果定义一个全局变量 , 在各线程中都可以访问到,除此之外 , 各线程还共享以下进程资源和环境:
  • 文件描述符
  • 每种信号的处理方式
  • 当前工作目录
  • 用户ID和组ID
  • 共享.text(代码段)  .data(数据段) .bss(未初始化数据段).heap(堆)
关系图:
一 Linux--多线程

文章插图
Linux线程控制POSIX线程库
  • POSIX线程(英语:POSIX Threads , 常被缩写为Pthreads)是POSIX的线程标准 , 定义了创建和操纵线程的一套API 。
  • 与线程有关的函数构成了一个完整的系列 , 绝大多数的名字都是以“pthread_”打头的 。
  • 使用线程库需要映入头文件pthread.h , 链接这些线程函数是 , 需要指明线程库名 , 所以编译时要加上选项-lpthread 。
注意: Linux内核没有提供线程管理的库函数 , 这里的线程库是用户提供的线程管理功能
错误检查:
  • 传统的一些函数是 , 成功返回0 , 失败返回-1 , 并且对全局变量errno赋值以指示错误 。
  • pthreads函数出错时不会设置全局变量errno(而大部分其他POSIX函数会这样做 , 不然这个全局变量就成为临界资源了) 。而是将错误代码通过返回值返回 。
  • pthreads同样也提供了线程内的errno变量 , 以支持其它使用errno的代码 。对于pthreads函数的错误 , 建议通过返回值判定 , 因为读取返回值要比读取线程内的errno变量的开销更小 。
线程创建int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);功能:创建一个线程 。参数:    thread:线程标识符地址    attr:线程属性结构体地址 , 通常设置为NULL    start_routine:线程函数的入口地址    arg:传给线程函数的个数返回值:    成功:0    失败:非0在一个线程中调用pthread_create()创建新的线程之后 , 当前线程从pthread_create()返回继续向下运行 , 而新的线程所执行的代码由我们传给pthread_create的函数指针start_routine决定 。
由于pthread_create的错误码不保存在errno当中 , 因此不能直接使用perror()打印错误信息 , 可以先用strerror()把错误码转成错误信息再打印 。
代码示例:
 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<pthread.h> //线程调度之后执行的任务 void *fun(void *arg) {    printf("新的线程执行任务 tid:%ld\n",pthread_self());    //退出当前函数体    return NULL; }int main(){    int ret = -1;    pthread_t tid = -1;    //创建一个线程    ret = pthread_create(&tid,NULL,fun,NULL);    if(0!=ret)    {      //根据错误号打印错误信息      printf("error information:%s\n",strerror(ret));      return 1;    }    printf("main thread.....tid:%lud\n",pthread_self());    return 0;}

经验总结扩展阅读