线程安全与线程同步

线程安全 (可重入函数)

线程之间共享全局数据段、静态数据,引起非线程安全。线程安全可以通过线程同步对临界资源访问进行控制来实现。

有些系统调用或者库函数的实现时发生不安全现象,在多线程环境下就需要使用这些函数的安全版本,即可重入函数。

例如:字符串分割函数

普通版本:char* strtok(char* sourstr,const char* flag)

可重入版本:char* strtok_r(char* sourstr,const char* flag,char ** res)

printf()不是线程安全函数

线程同步:

四种方式:信号量、互斥锁、读写锁、条件变量。用户可以通过这四个方式对线程进行同步操作。下面分别介绍一下

信号量:在进程间通信时我们已经了解过信号量了,这里与进程间的信号量作用相似,当线程访问一些有限的共享资源的时候,就必须做到线程同步访问。

信号量的使用方式:#include<semaphore.h>

                  初始化:int sem_init(sem_t *sem,int shared,int val);

信号量sem一般被定义在线程共享的全局数据段,sem_init函数将信号量sem 的初始值设置为val,shared参数控制这个信号量是否可以在多个进程之间共享,但是Linux对此不支持。

P操作:对信号量sem进行-1操作,如果结果小于0,此函数会阻塞,直到其他线程执行V操作。

              int sem_wait(sem_t *sem);

V操作:对信号量sem进行+1操作

               int sem_post(sem_t *sem);

销毁:销毁信号量

           int sem_destroy(sem_t *sem);

互斥锁:只能在线程之间使用的一种控制临界资源访问的机制,如果一个线程想要访问临界资源,必须先加锁,用完之后再解锁。当一个线程访问临界资源时,其他线程的访问就会阻塞,不能访问,直到该线程使用完解锁后。互斥锁一般放在线程共享的全局数据段。

互斥锁的使用方式:#include<pthread.h>

初始化:int pthread_mutex_init(pthread_mutex_t* mutex,pthread_mutexattr_t *attr);

加锁:int pthread_mutex_lock(pthread_mutex_t* mutex);

解锁:int pthread_mutex_unlock(pthread_mutex_t* mutex);

销毁锁:int pthread_mutex_destroy(pthread_mutex_t* mutex);

条件变量:用于线程之间同步共享数据的值,条件变量提供了一种线程间的通信机制:当共享数据达到某个值时,唤醒这个共享数据的线程。

条件变量的使用方式:#include<pthread.h>

初始化条件变量:int pthread_cond_init(pthread_cond_t* cond,pthread_condattr_t *cond_attr);

销毁条件变量:int pthread_cond_destroy(pthread_cond_t* cond);

以广播的方式唤醒所有等待条件变量的线程:int pthread_cond_broadcast(pthread_cond_t* cond);

唤醒一个等待目标变量的线程:int pthread_cond_signal(pthread_cond_t* cond);

等待目标条件变量:int pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex);

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值