个人主页:mooridy
专栏地址:Linux
关注我,和我一起学习更多计算机的知识!
临界资源:
多线程执行流共享的资源就叫做临界资源临界区:
每个线程内部,访问有临界资源的代码,就叫做临界区原子性:
不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用。
⼤部分情况,线程使⽤的数据都是局部变量,变量的地址空间在线程栈空间内,这种情况,变量归属单个线程,其他线程⽆法获得这种变量。
但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互。
多个线程并发的操作共享变量,可能会出现一些问题,比如下面这种情况。
![[Pasted image 20250328201239.png]]
像i++这样的操作并不是原子的,它的底层汇编代码有三句,即上图红色的三步。如果在这中间发生时钟中断,就会导致结果异常。
要解决这种问题,我们需要保证几个条件:
要实现这些条件,我们就需要一把锁,Linux上我们把这把锁叫做互斥量。
![[Pasted image 20250328202101.png]]
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
PTHREAD_MUTEX_INITIALIZER
是一个宏,它为互斥量提供了默认的初始值。使用这种方式初始化的互斥量,其生命周期与包含它的变量相同,并且不需要手动调用销毁函数来释放资源。这种方式适合那些在程序运行期间一直存在且不需要动态调整属性的互斥量。int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
mutex
:这是一个指向 pthread_mutex_t
类型的指针,代表要初始化的互斥量。在调用该函数时,需要提供一个有效的 pthread_mutex_t
变量的地址。attr
:这是一个指向 pthread_mutexattr_t
类型的指针,通常将其设置为 NULL
。当设置为 NULL
时,表示使用默认的互斥量属性。0
。int pthread_mutex_destroy(pthread_mutex_t *mutex);
PTHREAD_MUTEX_INITIALIZER
初始化的互斥量不需要销毁,因为它是静态分配的,其资源会在程序结束时自动释放。0
。int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
0
。pthread_mutex_lock
调用情况分析pthread_mutex_lock
函数会将互斥量锁定,同时返回成功。这意味着当前线程成功获得了对共享资源的访问权,其他线程在该互斥量解锁之前无法获得访问权。pthread_mutex_lock
调用会陷入阻塞(执行流被挂起)。此时,当前线程会暂停执行,直到互斥量被解锁,然后再次尝试获取互斥量。线程同步需要由条件变量来实现。
条件变量是一种机制。当线程持有锁进入临界区后,如果发现资源未就绪,它可以释放锁并进入等待状态。当其他线程将资源准备好后,会通过条件变量通知等待的线程。这样等待的线程就不需要频繁地检测资源是否就绪,一旦资源就绪就会被通知来访问资源,从而避免了 CPU 资源的浪费。
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
此函数用于初始化一个条件变量。
参数:
cond
:这是一个指向 pthread_cond_t
类型的指针,代表要初始化的条件变量。在调用该函数时,需提供一个有效的 pthread_cond_t
变量的地址,这样函数才能对其进行初始化操作。attr
:这是一个指向 pthread_condattr_t
类型的指针,通常将其设置为 NULL
。当设置为 NULL
时,表示使用默认的条件变量属性。如果需要自定义条件变量的属性,可先创建一个 pthread_condattr_t
类型的变量,对其进行相应的设置,然后将其地址传递给该参数。返回值:
0
。int pthread_cond_destroy(pthread_cond_t *cond);
该函数用于销毁一个已经初始化的条件变量。
参数:
cond
:这是一个指向 pthread_cond_t
类型的指针,代表要销毁的条件变量。在调用该函数时,需提供一个已经初始化的 pthread_cond_t
变量的地址。返回值:
0
。int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
此函数用于让当前线程在指定的条件变量上等待,直到其他线程通过 pthread_cond_signal
或 pthread_cond_broadcast
函数唤醒它。
参数:
cond
:这是一个指向 pthread_cond_t
类型的指针,代表要在这个条件变量上等待。当前线程会在该条件变量上进入阻塞状态,直到条件满足被唤醒。mutex
:代表一个互斥量。在调用 pthread_cond_wait
函数之前,当前线程必须已经锁定了该互斥量。在函数内部,它会自动解锁该互斥量,并让线程进入等待状态。当线程被唤醒后,它会自动重新锁定该互斥量。返回值:
0
。int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
这两个函数用于唤醒在指定条件变量上等待的线程。
pthread_cond_broadcast
函数:
该函数会唤醒所有在指定条件变量 cond
上等待的线程。
pthread_cond_signal
函数:
该函数会唤醒在指定条件变量 cond
上等待的一个线程。