• Linux关于线程的内容


    一、基本概念

      线程:在进程中负责执行代码的一个单位,进程的一部分,一个进程至少要有一个线程,也就是主线程,当然一个进程也可以有多个线程,这就需要创建了,下面会讲到线程的创建。

      进程中的代码段、只读段、全局段、静态数据段、堆、命令行、环境变量表、文件描述符、信号处理函数等这些资源对于线程来说都是共享的,但是栈空间却是私有的。

      线程是进程的一个实体,是操作体统独立调度和分派任务的基本单位。

    二、POSIX线程

     UNIX和Linux本身是不支持线程的,需要通过额外的线程库才可以使用,编译时需要:gcc name.c

    -lpthread

     对线程的操作包括创建线程、销毁线程、分离线程、联合线程、查询线程属性和设置线程属性。

     线程最需要解决的问题就是解决线程同步的问题。

    三、创建线程

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

      线程的相关函数比较长,但是还是比较好理解的。

      这个函数的功能就是创建线程,

      thread:返回值,获取线程id
         attr:返回值,获取线程属性
         start_routine:参数,注册线程的入口函数
         arg:给线程入口函数的参数

    #include <stdio.h>
    #include <pthread.h>
    
    void* pthread_run(void* arg)
    {
        
        while(1)
        {
            printf("呵呵,我是子线程 
    ",);
                    sleep(1);
        }
    }
    int main()
    {
        pthread_t ptid;
        int ret = pthread_create(&ptid,NULL,pthread_run,NULL);
        if(0 > ret)
        {
            perror("pthread_create");
            return -1;
        }
    
        while(1)
        {
            printf("我是主线程
    ");
            sleep(1);
        }
    }
                

       a、同一个进程的多个线程都在同一个地址空间内活动,所以对于进程来讲,线程的系统开销比较小,切换任务比较快,可以执行相同的代码,也可以执行不同的代码。

      b、main函数就是主线程,main函数返回就是主线程结束。主线程一结束,所有它的子线程也都结束。

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

    四、对线程的操作
     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 - 异步取消。
           被取消线程可以在任意时间取消,不是非得遇到取消点才能被取消。
            但是操作系统并不能保证这一点。
  • 相关阅读:
    NP数据库工具安装链接博客
    javascript mouseup , mousedown 和 拖拽事件 drag冲突的解决办法
    vscode 开启html代码自动补全
    spring 测试程序运行时间工具类StopWatch
    rabbmitmq 通过docker 方式启动无法打开管理界面的问题
    linux 测试端口开放工具 nmap
    html5--video 无法自动播放
    antd hooks --Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
    C#发送腾讯企业邮箱
    web安全漏洞简单总结
  • 原文地址:https://www.cnblogs.com/yyc954330712/p/9405095.html
Copyright © 2020-2023  润新知