zoukankan      html  css  js  c++  java
  • UNIX环境--线程

    一、线程的概念

      1、线程在进程中是负责执行代码的一个单位,可以说线程是进程的一部分。一个进程中至少要有一个主线程,进程可以拥有多个线程。

      2、线程和进程一样,线程会共享进程的一些信息。比如,代码段、全局段、静态数据区、堆、命令行、环境变量表等,但栈是每个线程私有的。

      3、严格来说,线程是进程的一个实体,是操作系统独立调度和分派任务的基本单位。

    二、POSIX线程

      UNIX和Linux不支持线程处理,但有额外的线程库可以调用。在编辑时要加<pthread.h>的线程库头文件,在编译时要加 -lpthread

    三、创建线程

      int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

      功能:创建线程

      thread:返回值,获取线程id

      attr:返回值,获取线程属性

      start_routine:参数,注册线程的入口函数

      arg:给线程入口函数的参数

      1、同一个进程的多个线程都在同一个地址空间内活动,因此相对于进程,线程的系统开销小,任务切换快,它们可以执行相同的代码,也可以执行不同的代码。

      2、线程间的数据交换不需要依赖于类似IPC的特殊通信机制,简单而高效,每个线程拥有自己独立的线程ID、寄存器信息、函数栈、错误码和信号掩码,线程之间存在优先级的差异。

      3、main函数即主线程,main函数返回即主线程结束,主线程结束即进程结束,进程一但结束其所有的线程即结束。

      4、应设法保证在线程过程函数执行期间,其参数所指向的目标持久有效。

    四、对线程的操作

      1、等待线程

      int pthread_join (pthread_t thread, void** retval);  

      功能:等待thread参数所标识的线程结束

      retval:返回值,线程入口函数的返回值

      返回值:成功返回0,失败返回错误码。

      线程过程函数将所需返回的内容放在一块内存中,返回该内存的地址,要保证这块内存在函数返回后,即线程结束,以后依然有效;  

      若retval参数非NULL,则pthread_join函数将线程过程函数所返回的指针,拷贝到该参数所指向的内存中;

      若线程过程函数所返回的指针指向动态分配的内存,则还需保证在用过该内存之后释放之。

      2、获取线程id

      pthread_t pthread_self (void);

      功能:返回当前线程的id,此函数不会执行失败。

      3、比较两个线程

      int pthread_equal (pthread_t t1, pthread_t t2);  

      功能:比较两个id是否是同一个线程      

      如果两个线程id相等,则返回非零,否则返回0。

      某些实现的pthread_t不是unsigned long int类型,可能是结构体类型,无法通过“==”判断其相等性。

      4、终止线程

      1) 从线程过程函数中return。

      2) 调用pthread_exit函数。

      void pthread_exit (void* retval);

      retval和线程过程函数的返回值语义相同。

      5、线程的执行轨迹

      1) 同步方式(非分离状态):

      创建线程之后调用pthread_join函数等待其终止,并释放线程资源。

      2) 异步方式(分离状态):

      无需创建者等待,线程终止后自行释放资源。

      int pthread_detach (pthread_t thread);  

      功能:使线程进入分离(DETACHED)状态。

      返回值:成功返回0,失败返回错误码。

      处于分离状态的线程终止后自动释放线程资源,且不能被pthread_join函数等待。

      6、取消线程

      1) 向指定线程发送取消请求

      int pthread_cancel (pthread_t thread);

    ​  成功返回0,失败返回错误码。

    ​  注意:只是向线程发出取消请求,并不等待线程终止。

      缺省情况下,线程在收到取消请求以后,并不会立即终止,而是仍继续运行,直到其达到某个取消点。

      在取消点处,线程检查其自身是否已被取消了,并做出相应动作。

      当线程调用一些特定函数时,取消点会出现。

      2) 设置调用线程的可取消状态

      int pthread_setcancelstate (int state,int* oldstate);

      成功返回0,并通过oldstate参数输出原可取消状态(若非NULL),失败返回错误码。

      state取值:

         PTHREAD_CANCEL_ENABLE:接受取消请求

         PTHREAD_CANCEL_DISABLE:忽略取消请求。

      

      3) 设置调用线程的可取消类型

      int pthread_setcanceltype (int type, int* oldtype);

    ​    

      成功返回0,并通过oldtype参数输出原可取消类型(若非NULL),失败返回错误码。

    ​  type取值:

           PTHREAD_CANCEL_DEFERRED延迟取消(缺省)。

                       被取消线程在接收到取消请求之后并不立即响应,而是一直等到执行了特定的函数(取消点)之后再响应该请求。

           PTHREAD_CANCEL_ASYNCHRONOUS - 异步取消。

                    被取消线程可以在任意时间取消,不是非得遇到取消点才能被取消。

               但是操作系统并不能保证这一点。

  • 相关阅读:
    函数进阶,递归,二分法查找
    内置函数
    IDEA使用maven创建web工程并完善的过程
    后端传入前端的数据的属性名全部为小写的解决方法
    今日总结,复习了很多知识
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ztreeoneServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; 错误的解决方法
    xxx cannot be resolved to a type 的可能的解决方法,mybatis的Example类不存在
    记录一下Spirng Initializr初始化项目的时候pom文件的内容
    使用nacos进行服务注册的配置
    org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing问题的一种解决方法参考
  • 原文地址:https://www.cnblogs.com/goul/p/9439184.html
Copyright © 2011-2022 走看看