Linux下线程间同步-互斥锁 原创 Linux平台 2022年3月31日 16:16 夏至未至 759 当前内容 2874 字,在路上,马上到,马上到 ### 目录 [TOC] ### 何为互斥锁 互斥锁(互斥量),每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束后解锁。资源还是共享的,线程间也还是竞争的,但通过锁将资源的访问变为互斥操作。本质就是一个特殊的全局变量 ### 互斥锁特点 #### 原子性 把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果一个线程锁定了一个互斥量,没有其他线程在同一时间可以成功锁定这个互斥量; #### 唯一性 如果一个线程锁定了一个互斥量,在它解除锁定之前,没有其他线程可以锁定这个互斥量; #### 非繁忙等待 如果一个线程已经锁定了一个互斥量,第二个线程又试图去锁定这个互斥量,则第二个线程将被挂起(不占用任何cpu资源),直到第一个线程解除对这个互斥量的锁定为止,第二个线程则被唤醒并继续执行,同时锁定这个互斥量。 ### 互斥锁实现 #### 实现流程 1. 在访问共享资源后临界区域前,对互斥锁进行加锁; 2. 在访问完成后释放互斥锁导上的锁。在访问完成后释放互斥锁导上的锁; 3. 对互斥锁进行加锁后,任何其他试图再次对互斥锁加锁的线程将会被阻塞,直到锁被释放。对互斥锁进行加锁后,任何其他试图再次对互斥锁加锁的线程将会被阻塞,直到锁被释放。 #### 实现方法 // 初始化一个互斥锁。 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 #include #include #include #include char* buf[5]; int pos; // 全局互斥量 pthread_mutex_t mutex; void *task(void *p) { pthread_mutex_lock(&mutex); buf[pos] = (char *)p; sleep(1); pos++; pthread_mutex_unlock(&mutex); } int main(void) { pthread_mutex_init(&mutex, NULL); pthread_t tid, tid2; pthread_create(&tid, NULL, task, (void *)"AAAA"); pthread_create(&tid2, NULL, task, (void *)"BBBB"); pthread_join(tid, NULL); pthread_join(tid2, NULL); pthread_mutex_destroy(&mutex); int i = 0; printf("数组中的内容为:"); for(i = 0; i < pos; ++i) { printf("========%s ", buf[i]); } printf("\n"); return 0; } ##### 非阻塞模式 #include #include #include #include int main (void) { int err; struct timespec tout; struct tm *tmp; char buf[64]; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock (&lock); printf ("mutex is locked\n"); clock_gettime (CLOCK_REALTIME, &tout); tmp = localtime (&tout.tv_sec); strftime (buf, sizeof (buf), "%r", tmp); printf ("current time is %s\n", buf); tout.tv_sec += 10; err = pthread_mutex_timedlock (&lock, &tout); clock_gettime (CLOCK_REALTIME, &tout); tmp = localtime (&tout.tv_sec); strftime (buf, sizeof (buf), "%r", tmp); printf ("the time is now %s\n", buf); if (err == 0) printf ("mutex locked again\n"); else printf ("can`t lock mutex again:%s\n", strerror (err)); return 0; } 本文标题: Linux下线程间同步-互斥锁 本文作者: 夏至未至 发布时间: 2022年3月31日 16:16 最近更新: 2022年3月31日 16:16 原文链接: 许可协议: 署名-非商业性-禁止演绎 4.0 国际(CC BY-NC-ND 4.0) 请按协议转载并保留原文链接及作者 线程间同步(5) 上一个 Linux下线程间同步-条件变量 下一个 Linux下线程间同步-四种机制 当前文章评论暂未开放,请移步至留言处留言。