线程同步 & 线程安全

1、线程同步
(1)同步: 多进程或者多线程访问临界资源时,必须进行同步控制。多进程或者多线程的执行并不完全是绝对的并行运行,有可能主线程需要等待函数线程的某些条件的发生。

(2)多线程之间有几个特殊的临界资源:
全局数据、堆区数据、文件描述符 多线程之间共用

(3)线程间同步控制方式:

a. 信号量
获取: int sem_init(sem_t *sem, int shared , int value);
sem: 是一个 sem_t 类型指针,指向信号量对象。
shared: 是否能在多进程间共享, Linux 不支持, 0
value: 信号量的初始值
返回值: 0 成功 -1 失败
P 操作: int sem_wait(sem_t *sem); // 阻塞运行
V 操作: int sem_post(sem_t *sem);
删除: int sem_destroy(sem_t *sem);

b. 互斥锁
概念:完全控制临界资源,如果一个线程完成加锁操作,则其他线程无论如何都无法再完成加锁,也就无法对临界资源进行访问。

初始化:int pthread_mutex_init(pthread_mutex_t *mutex,
pthread_mutex_attr_t *attr);
加锁:int pthread_mutex_lock(pthread_mutex_t *mutex); // 阻塞运行
int pthread_mutex_trylock(pthread_mutex_t *mutex); //非阻塞版本
解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);
释放:int pthread_mutex_destroy(pthread_mutex_t *mutex);

c.条件变量

2、线程安全 —> 可重入函数有些库函数会使用线程间共享的数据,如果没有同步控制,线程操作就是不安全的,所以,我们使用这样一些函数时,就必须使用其安全的版本 —》可重入函数.
这里写图片描述

3、 线程中 fork 的使用,锁的变化在线程中调用 fork 函数,子进程只会启用调用 fork 函数的那条线程,其他线程不会启用。

子进程会继承其父进程的锁以及锁的状态,但是父子进程用的不是同一把锁,父进程解锁并不会影响到子进程的锁,所以子进程有可能死锁。

pthread_atfork(void (*prepare)(void), void (*parent)(void ), void (*child)(void));

指定在 fork 调用之后,创建子进程之前, 调用 prepare 函数,获取所有的锁,然后创建子进程, 子进程创建以后,父进程环境中调用 parent 解所有的锁,子进程环境中调用 child 解所有的锁,然后 fork 函数再返回。这样保证了 fork 之后,子进程拿到的锁都是解锁状态,避免死锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值