linux线程

线程

线程创建

#include<pthread.h>
int pthread_creat(                  //创建线程,成功返回0,失败返回errcode
        pthread_t   *thread,        //线程号     
        pthread_attr_t *attr,       //
        void *(*func)(void*),       //线程需要运行的函数
        void *arg                   //传递给func的参数      
                 )

int pthread_join(                   //等待线程终止,成功返回0,失败返回errcode
        pthread_t   pthread,        //所等待的线程号
        void*   retval              //指向线程返回值
)      

在linux中使用pthread.h头文件需要连接lpthread库

线程池

组成成分

  1. 线程池管理器
  2. 工作线程
  3. 任务接口
  4. 任务队列

工作流程

    1. 初始化线程池
    2. 堵塞任务线程
    2. 将任务添加进人物队列
    3. 判断是否有空闲线程
    4. 唤醒线程
    5. 完成任务
    6. 重新堵塞线程

常见线程池

  • 单线程池

    每次只有一个线程工作

  • 固定线程池

    线程池中线程的数量固定,当达到线程池最大数量时,后续任务进入等待队列

  • 可缓存线程池

    当任务超出线程数量时,添加线程,当线程池空闲线程数量过多时,回收部分空间

  • 无限制线程池

    线程池大小无限制,支持定时和周期性执行

优点

    1. 控制线程产生数量,控制线程对象的内存消耗
    2. 降低系统开销和资源消耗
    3. 提高系统响应速度

通信

线程

进程

  • 命名通道
    1. 通道是一个队列而不是常规文件
    2. 其读和写是原子操作
  • 共享内存
    1. 共享内存段不依赖于进程存在
    2. 共享内存段的名字叫关键字
    3. 关键字是一个整型数
    4. 共享内存段有自己的拥有者己权限位
    5. 进程可以连接共享内存段,并获得指针
  • 文件锁
  • 信号量
  • 相关函数
    1. select、poll
    2. mkfio
    3. shmget、shmat、shmctl、shmdt(共享内存)
    4.semget、semctl、semop

同步

互斥量

#include <pthread.h>
int pthread_mutex_lock(                 //等待互斥锁解开后锁住互斥量,成功返回0
            pthread_mutex_t *mutex     //指向互斥锁
)

int pthread_mutex_unlock(                  //解锁互斥量,成功返回0
            pthread_mutex_t *mutex,        //指向互斥量
)

条件变量

#include <pthread.h>
int pthread_cond_wait(                      //挂起线程,等待信号量,成功返回0
            pthread_cond_t  *cond,          //
            pthread_mutex_t *mutex,         //指向互斥锁对象
)

int pthread_cond_signal(                    //唤醒等待线程,成功返回0
        pthread_cond_t *cond)               //指向条件变量

pthread_cond函数总是和互斥锁在一起使用。此函数先自动释放指定的锁,然后等待条件变量的变化。如果在调用此函数之前,互斥量mutex并没有被锁住,函数执行的结果是不确定的。在返回原调用函数之前,此函数自动将指定的互斥量重新锁住。

信号量

#include <semaphore.h>
int sem_init(sem_t *sem,                //sem地址  
        int pshared,                   //0表示本进程中多个线程间同步,非0表示可以跨进程的同步操作
        unsigned int value);             //信号量初值(计数器的值)
 P   int sem_wait(sem_t *sem);   // sem-1 如果小于0就阻塞
 V    int sem_post(sem_t *sem);   // sem+1

读写锁

//初始化和销毁
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
// 成功则返回0, 出错则返回错误编号.

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
// 成功则返回0, 出错则返回错误编号.

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
// 成功则返回0, 出错则返回错误编号.

安全

在多线程程序中,很有可能会将同一个文件描述符传递给两个不同的线程。即传递给它们的两个值指向同一个文件描述符。显然如果一个线程中的函数关闭了这个文件,此文件描述符对此进程中的任何线程来说都已经被关闭。

fork创建了一个新的进程,并把原调用进程的数据和代码复制给这个新的进程。如果线程中的某函数调用了 fork,只有调用fork的线程在新的进程中运行

posted @ 2019-07-26 11:23  菜鸟当家  阅读(217)  评论(0编辑  收藏  举报