一些基础概念
临界资源: 任一时刻只允许一个线程访问的共享资源
临界区: 访问临界资源的代码
原子性: 不会被任何调度机制打断的操作,该操作只有两态:要么完成,要么未完成。
互斥: 任何时刻,互斥可以保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用,而锁就是实现互斥的。
同步: 同步是一种机制,用于协调不同进程、线程或设备之间的操作,确保它们按照预期的顺序和方式进行。同步的目的是保持数据的一致性和系统的稳定性。
互斥锁
线程之间共享同一地址空间和资源,而线程的并发执行也可能导致资源竞争的问题。为了解决线程之间资源竞争的问题,linux系统提供了互斥锁(Mutex)这一机制。
在使用互斥锁的过程中,当一个线程要访问共享资源时,首先会尝试获取互斥锁。如果锁已被其他线程占用的,则该线程会被阻塞,直到其他线程释放锁为止;而当线程访问完共享资源后,需要显式地释放互斥锁,以便其他线程可以继续访问共享资源。
使用互斥锁的一些API函数
#include <pthread.h>
#include <time.h>
pthread_mutex_t local_mutex;//定义锁
// 初始化一个互斥锁。后面那个参数是他的属性。
int pthread_mutex_init(pthread_mutex_t &mutex, const pthread_mutexattr_t *attr);
// 对互斥锁上锁,若互斥锁已经上锁,则调用者一直阻塞,
// 直到互斥锁解锁后再上锁。
int pthread_mutex_lock(pthread_mutex_t *mutex);
// 调用该函数时,若互斥锁未加锁,则上锁,返回 0;
// 若互斥锁已加锁,则函数直接返回失败,即 EBUSY。
int pthread_mutex_trylock(pthread_mutex_t *mutex);
// 当线程试图获取一个已加锁的互斥量时,pthread_mutex_timedlock 互斥量
// 原语允许绑定线程阻塞时间。即非阻塞加锁互斥量。
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,
const struct timespec *restrict abs_timeout);
// 对指定的互斥锁解锁。
int pthread_mutex_unlock(pthread_mutex_t *mutex);
// 销毁指定的一个互斥锁。互斥锁在使用完毕后,
// 必须要对互斥锁进行销毁,以释放资源。
int pthread_mutex_destroy(pthread_mutex_t *mutex);
互斥锁的阻塞模式
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<time.h>
char *buf[5];
int pos;
pthread_mutex_t mutex;
void* task(void *p)
{
pthread_mutex_lock(&mutex);
buf[pos]=(char*)p;
pos++;
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t id1,id2;
pthread_mutex_init(&mutex,NULL);
pthr