Linux学习-线程

目录

线程

    线程相关的函数接口

线程分离属性

线程互斥

临界资源、临界区

死锁

信号量


线程


    1.基本概念:
        线程:线程是一个轻量级的进程,位于进程空间内部,一个进程中可以创建多个线程

    2.线程创建:
        线程独占栈空间,文本段、数据段和堆区与进程共享
    
    3.线程调度:
        与进程调度是一样的
        宏观并行,微观串行
    
    4.线程消亡:
        与进程消亡是一样的

    5.进程和线程的区别:
        进程是操作系统资源分配的最小单元
        线程是CPU任务调度的最小单元

    6.多进程和多线程的优缺点:
        效率:多线程 > 多进程 
             多线程只需在同一进程空间内切换
             多进程需要在不同的空间中切换
        
        通信:多线程 > 有进程
            线程共享全局变量,可以通过全局变量实现数据通信
            进程空间是独立的,没有共享空间,通信实现比较复杂

        通信实现:多进程 > 多线程
            线程共享空间操作时会引发资源竞争
            进程没有共享空间,不存在资源竞争的问题
        
        安全:多进程 > 多线程
            一个进程异常不会影响其余进程空间
            一个线程异常结束会导致进程异常结束,进程异常结束,该进程内所有线程任务均无法向下执行
    


    线程相关的函数接口


        创建: fork      pthread_create 
        退出: exit      pthread_exit 
        回收: wait      pthread_join 

        1.pthread_create
          int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);
          功能:
            在该进程中创建一个新的线程
          参数:
            thread:存放线程ID空间首地址
            attr:线程属性空间首地址
            start_routine:线程要执行的函数的入口
            arg:给线程函数的参数
          返回值:
            成功返回0 
            失败返回错误码

        编译时加   -lpthread选项  ,要链接pthread。

        2.pthread_self
          pthread_t pthread_self(void);
          功能:
            获得调用该函数线程的ID  

      

        3.pthread_exit 
          void pthread_exit(void *retval);
          功能:
            让调用该函数的线程任务结束
          参数:
            retval:线程结束的值
        
        4.pthread_join 
          int pthread_join(pthread_t thread, void **retval);
          功能:
            回收线程空间
          参数:
            thread:线程的ID号
            retval:存放线程结束状态空间的首地址
          返回值:
            成功返回0 
            失败返回错误码

        这个函数也会阻塞主函数,等待线程结束回收后在进行运行。

线程分离属性


    线程结束后,自动回收线程空间

    pthread_attr_init
    int pthread_attr_init(pthread_attr_t *attr);
    功能:
      线程属性初始化

    pthread_attr_destroy
    int pthread_attr_destroy(pthread_attr_t *attr);
    功能:
      线程属性销毁

    pthread_attr_setdetachstate 
    int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
    功能:
      设置分离属性 
      PTHREAD_CREATE_DETACHED   分离属性
      PTHREAD_CREATE_JOINABLE   加入属性(默认)

void * 是 C 语言中的一种通用指针类型。它表示一个指向未知类型的指针,也称为“无类型指针”。这意味着它可以指向任何类型的数据,因为它没有指定类型。void * 可以用于在函数中传递任意类型的指针,或者用于从函数中返回指向任意类型的指针。

练习:定义一个学生结构体
      struct student 
      {
        char name[32];
        char sex;
        int age;
        int score;
      };

      创建两个线程,线程1负责从终端接收学生信息
                  线程2负责将学生信息打印在终端

线程互斥

    1.互斥锁:防止资源竞争

所有的参数上下都要加锁解锁。
    2.函数接口:
      pthread_mutex_init:
      int pthread_mutex_init(pthread_mutex_t *restrict mutex,
           const pthread_mutexattr_t *restrict attr);
      功能:
        互斥锁初始化
      参数:
        mutex:互斥锁空间首地址
        attr:互斥锁的属性(默认为NULL)
      返回值:
        成功返回0 
        失败返回错误码 

      pthread_mutex_destroy:
      int pthread_mutex_destroy(pthread_mutex_t *mutex);
      功能:
        互斥锁销毁
      参数:
        mutex:互斥锁空间首地址
      返回值:
        成功返回0 
        失败返回错误码 

      pthread_mutex_lock:
      int pthread_mutex_lock(pthread_mutex_t *mutex);
      功能:
        上锁

      pthread_mutex_unlock:
      int pthread_mutex_unlock(pthread_mutex_t *mutex);
      功能: 
        解锁

临界资源、临界区


      加锁解锁中间的代码称为临界资源、临界区
      同一时刻临界资源不能同时执行,只能执行其中一个临界资源代码

    4.原子操作:
      CPU最小的一次不能被任务调度打断的操作称为原子操作

    5.互斥锁只能解决资源竞争的问题,无法同步代码(没有先后执行的顺序关系)

死锁

    多线程操作互斥锁,导致多个线程均无法向下执行的状态称为死锁状态简称为死锁

    死锁产生的四个必要条件:
      1.互斥条件
      2.不可剥夺条件
      3.请求保持
      4.循环等待

    避免产生死锁:
      1.pthread_mutex_trylock 替代 pthread_mutex_lock

        trylock是加不上锁就不会等待,继续做其他事,lock会循环等待
      2.加锁顺序保持一致

信号量


    信号量是一种资源,可以被初始化、申请、释放、销毁

    P操作:申请资源
    V操作:释放资源

    sem_init  
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    功能:
      初始化信号量
    参数:
      sem:信号量空间首地址
      pshared:
        0 一个进程中的所有线程间共享
        非0 进程间共享 
      value:
        初始化的值
    返回值:
      成功返回0 
      失败返回-1 
    
    sem_destroy:
    int sem_destroy(sem_t *sem);
    功能:
      信号量的销毁
    参数:
      sem:信号量空间首地址
    返回值:
      成功返回0 
      失败返回-1 

    sem_wait:
    int sem_wait(sem_t *sem);
    功能:
      申请信号量

    sem_post:
    int sem_post(sem_t *sem);
    功能:
      释放信号量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值