线程与线程控制(Linux)

一、介绍

线程作为系统执行的最小单位,同一个进程之间的不同线程仅存在私有栈区,除此之外全部共享。

二、线程函数介绍

头文件

#include <pthread.h>
在编译时需要链接动态库 gcc main.c -o app -lpthread

1、创建线程

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
返回值:
    成功:0
    失败:返回错误号
参数:
    thread:创建线程的线程号
    attr:线程属性,NULL为默认属性
    start_routine:线程的执行函数
    arg:执行函数的参数

2、查看当前线程号

pthread_t pthread_self(void);
返回值:
    成功:当前线程号
    不会失败

3、线程退出

1、自行退出,自杀
void pthread_exit(void *retval);
参数:
    retval:线程退出的遗言

2、强制退出,他杀
int pthread_cancel(pthread_t thread);
返回值:
    成功:0
    失败:-1
参数:
    thread:需要退出的线程号

4、线程回收

int pthread_join(pthread_t thread, void **retval); 
返回值:
    成功:0
    失败:-1
参数:
    thread:要回收的线程号
    retval:由ptread_exit函数传递的值

三、线程控制函数

线程控制为:互斥和同步

互斥:对临界资源无差别的排他性访问

同步:对临界资源按照一定顺序访问

条件变量:根据信号随机唤醒一个线程持有

1、互斥函数

头文件<pthread.h>

1、初始化
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
返回值:
    成功:0
    失败:非零
参数:
    mutex:要初始化的互斥锁
    attr:要初始化的值,NULL表示默认锁

2、加锁,阻塞等待
int pthread_mutex_lock(pthread_mutex_t *mutex);
返回值:
    成功:0
    失败:非零
参数:
    mutex:互斥锁

3、解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
返回值:
    成功:0
    失败:非零
参数:
    mutex:互斥锁

4、销毁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
返回值:
    成功:0
    失败:非零
参数:
     mutex:互斥锁

5、trylock,尝试加锁,当锁未被释放立即返回
int pthread_mutex_trylock(pthread_mutex_t *mutex);
返回值:
    成功:0
    失败:非零,E_AGAIN
参数:
    mutex:互斥锁

2、同步函数(信号量)

头文件<semaphore.h>

1、无名信号初始化
int sem_init(sem_t *sem, int pshared, unsigned int value);
返回值:
    成功:0
    失败:-1
参数:
    sem:信号量
    pshared:
        0:线程间使用
        !0:进程间使用
    value:初始化值
        0:阻塞
        1:释放,可以执行

2、无名信号销毁信号量
int sem_destroy(sem_t *sem);
返回值:
    成功:0
    失败:-1
参数:
    sem:信号量

3、等待信号, sem=sem-1
int sem_wait(sem_t *sem);
返回值:
    成功:0
    失败:-1
参数:
    sem:信号量

4、释放信号量,sem=sem+1
int sem_post(sem_t *sem);
返回值:
    成功:0
    失败:-1
参数:
    sem:信号量

5、超时等待
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
返回值:
    成功:0
    失败:-1
参数:
    sem:信号量
    abs_timeout:超时时间
        struct timespec {undefined
            time_t tv_sec; // seconds
            long tv_nsec; // and nanoseconds
        };
        clock_gettime(CLOCK_REALTIME, &ts);    获取当前时间    
        abs_timeout.sec+=value;    重新填充时间

6、有名信号量打开
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
返回值:
    成功:返回信号量地址
    失败:SEM_FAILED
参数:
    name:信号量名称
    oflag:
        O_CREAT:如果不存在就创建
        O_CREAT|O_EXCL:如果名称为输入名称的信号量已存在则返回失败
    mode:创建信号量的权限,建议0664    
    value:创建时信号量的初始值,如果已存在则则忽略

7、有名信号量关闭 (关闭并未从系统删除,需要使用unlink从系统删除)
int sem_close(sem_t *sem);
返回值:
    成功:0
    失败:-1
参数:
    sem:信号量的地址

8、有名信号量删除
int sem_unlink(const char *name);
返回值:
    成功:0
    失败:-1
参数:
    name:需要删除信号量的名称

3、条件变量

头文件<pthread.h>

1、初始化
    静态初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    动态初始化
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
返回值:
    成功:0
    失败:非零
参数:
    cond:变量
    attr:通常为NULL

2、销毁
int pthread_cond_destroy(pthread_cond_t *cond);
返回值:
    成功:0
    失败:非零
参数:
    cond:变量

3、等待
(1)有超时
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
返回值:
    成功:0
    失败:非零
参数:
    cond:变量
    mutex:互斥锁
    abstime:超时时间
        struct timespec {undefined
            time_t tv_sec; // seconds
            long tv_nsec; // and nanoseconds
        };
        clock_gettime(CLOCK_REALTIME, &ts);    获取当前时间    
        abs_timeout.sec+=value;    重新填充时间
(2)阻塞等待
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
返回值:
    成功:0
    失败:非零
参数:
    cond:变量
    mutex:互斥锁

使用流程:
(1)pthread_mutex_lock()上锁,
(2)pthread_cond_wait()等待,等待过程分解为为:解锁--条件满足--加锁
(3)pthread_mutex_unlock()解锁。   

4、激活
(1)激活一个
int pthread_cond_signal(pthread_cond_t *cond);
返回值:    
    成功:0
    失败:非零
参数:
    cond:变量
(2)全部激活
int pthread_cond_broadcast(pthread_cond_t *cond);
返回值:
    成功:0
    失败:非零
参数:
    cond:变量

4、自旋锁

1、初始化锁
int pthread_spin_init(pthread_spinlock_t* lock,int pshared);
返回值:
    成功:0
    失败:非零
参数:
    lock:自旋锁
    pshared:
        PTHREAD_PROCESS_SHARED:任意进程可访问
        PTHREAD_PROCESS_PRIVATE:单一进程的线程间访问
    
2、销毁锁
int pthread_spin_destorya(pthread_spinlock_t* lock);
返回值:
    成功:0
    失败:非零

参数:
    lock:自旋锁

3、阻塞加锁
int pthread_spin_lock(pthread_spinlock_t* lock);
返回值:
    成功:0
    失败:非零
        EDEADLK:死锁
        EBUSY:持有失败
参数:
    lock:自旋锁

4、非阻塞加锁
int pthread_spin_trylock(pthread_spinlock_t* lock);
返回值:
    成功:0
    失败:非零
        EDEADLK:死锁
        EBUSY:持有失败
参数:
    lock:自旋锁

5、解锁
int pthread_spin_unlock(pthread_spinlock_t* lock);
返回值:
    成功:0
    失败:非零
参数:
    lock:自旋锁

5、读写锁

1、初始化
    (1)动态初始化
int pthread_rwlock_init(pthread_rwlock_t* rwlock);
返回值:
    成功:0
    失败:非零
参数:
    rwlock:读写锁

    (2)静态初始化
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

2、申请读锁
int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock);
返回值:
    成功:0
    失败:非零
参数:
    rwlock:读写锁

2、尝试申请读锁
int pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock);
返回值:
    成功:0
    失败:非零
参数:
    rwlock:读写锁
    
3、申请写锁
int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock);
返回值:
    成功:0
    失败:非零
参数:
    rwlock:读写锁

4、尝试申请写锁
int pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock);
返回值:
    成功:0
    失败:非零
参数:
    rwlock:读写锁

5、解锁
int pthread_rwlock_unlock(pthread_rwlock_t* rwlock);
返回值:
    成功:0
    失败:非零
参数:
    rwlock:读写锁

6、销毁锁
int pthread_rwlock_destroy(pthread_rwlock_t* rwlock);
返回值:
    成功:0
    失败:非零
参数:
    rwlock:读写锁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值