当前位置:首页>Linux>Linux C线程间通讯接口,互斥量和条件变量

Linux C线程间通讯接口,互斥量和条件变量

  • 2026-10-12 02:06:36
Linux C线程间通讯接口,互斥量和条件变量

在Linux C应用编程中,多线程是一种常用的工作方式,用于提高应用的并发性和响应性。

为了满足线程间数据通讯、同步等需求,Linux C提供了互斥量和条件变量接口,来解决对于资源的竞态处理以及线程同步的功能。 对于互斥量和条件变量,优先选择标准C语言库中的实现,具有更好的跨平台兼容性,详细见文档如下所示。

  • C语言线程库,threads.h (互斥量)
  • C语言线程库,threads.h (条件变量)

本节中将进行互斥量和条件变量的说明。

互斥量功能说明

互斥量是一种同步机制,用于确保同一时间只有一个线程可以访问共享资源。对于Linux C应用中,互斥量的相关接口也位于pthread.h头文件中,通过pthread_mutex*系列函数来实现。

另外,对于互斥量来说说,还支持设置互斥量的类型,来改变互斥量的行为,通过pthread_mutexattr*系列函数来实现。另外这个系列中的pthread_mutexattr_settype和pthread_mutexattr_gettype函数,需要全局宏定义-D_XOPEN_SOURCE=600才能使用。

函数
功能
pthread_mutex_init
初始化互斥量
pthread_mutex_lock
加锁
pthread_mutex_unlock
解锁
pthread_mutex_destroy
销毁互斥量
pthread_mutex_trylock
尝试加锁,如果互斥量已被其他线程持有,则返回EBUSY,否则返回0
pthread_mutexattr_init
初始化互斥量属性
pthread_mutexattr_destroy
销毁互斥量属性
pthread_mutexattr_settype
设置互斥量类型
pthread_mutexattr_gettype
获取互斥量类型

对于上述接口,常用的函数说明如下所示。

// 初始化互斥量// @param __mutex 互斥量指针// @param __mutexattr 互斥量属性指针// @return 0 成功,-1 失败,设置errnointpthread_mutex_init(pthread_mutex_t *__mutex,constpthread_mutexattr_t *__mutexattr)// 互斥量加锁// @param __mutex 互斥量指针// @return 0 成功,-1 失败,设置errnointpthread_mutex_lock(pthread_mutex_t *__mutex)// 互斥量解锁// @param __mutex 互斥量指针// @return 0 成功,-1 失败,设置errnointpthread_mutex_unlock(pthread_mutex_t *__mutex)// 初始化互斥量属性// @param __attr 互斥量属性指针// @return 0 成功,-1 失败,设置errnointpthread_mutexattr_init(pthread_mutexattr_t *__attr);// 获取互斥量属性类型// @param __attr 互斥量属性指针// @param __kind 互斥量属性类型指针// @return 0 成功,-1 失败,设置errnointpthread_mutexattr_gettype(constpthread_mutexattr_t *__restrict __attr, int *__restrict __kind)// 设置互斥量属性类型// @param __attr 互斥量属性指针// @param __kind 互斥量属性类型// @return 0 成功,-1 失败,设置errnointpthread_mutexattr_settype(pthread_mutexattr_t *__attr, int __kind);

对于互斥量属性类型配置,支持以下几种。

  • PTHREAD_MUTEX_NORMAL:普通互斥量,加锁时会阻塞其他线程,直到当前线程解锁。
  • PTHREAD_MUTEX_RECURSIVE:递归互斥量,允许一个线程重复加锁,但是其他线程不能加锁。
  • PTHREAD_MUTEX_ERRORCHECK:错误检查互斥量,加锁时会检查是否有其他线程正在解锁,如果有则返回EDEADLK。
  • PTHREAD_MUTEX_DEFAULT:默认互斥量,与普通互斥量相同。

无特殊需求时,初始化时设置为普通互斥量即可。

条件变量功能说明

条件变量线程的同步机制,允许线程在特定条件未满足时挂起(进入睡眠状态),并在其他线程修改了该条件并发出信号后被唤醒。另外在设计上,条件变量支持超时自动唤醒功能,可以用于模拟类似软件定时器的操作。

函数
功能
pthread_cond_init
初始化条件变量
pthread_cond_destroy
销毁条件变量
pthread_cond_wait
等待条件变量
pthread_cond_timedwait
带超时等待条件变量
pthread_cond_signal
信号条件变量
pthread_condattr_init
初始化条件变量属性
pthread_condattr_destroy
销毁条件变量属性
pthread_condattr_getclock
获取条件变量属性中的时钟特性
pthread_condattr_setclock
设置条件变量属性中的时钟特性

对于上述接口,常用的函数说明如下所示。

// 初始化条件变量// @param __cond 条件变量指针// @param __cond_attr 条件变量属性指针// @return 0 成功,-1 失败,设置errnointpthread_cond_init(pthread_cond_t *__restrict __cond, constpthread_condattr_t *__restrict __cond_attr)// 触发条件变量// @param __cond 条件变量指针// @return 0 成功,-1 失败,设置errnointpthread_cond_signal(pthread_cond_t *__cond)// 等待条件变量// @param __cond 条件变量指针// @param __mutex 互斥量指针// @return 0 成功,-1 失败,设置errnointpthread_cond_wait(pthread_cond_t *__restrict __cond,  pthread_mutex_t *__restrict __mutex)// 带超时等待条件变量// @param __cond 条件变量指针// @param __mutex 互斥量指针// @param __abstime 超时时间指针// @return 0 成功,-1 失败,设置errnointpthread_cond_timedwait(pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex, const struct timespec *__restrict __abstime)// 初始化条件变量属性// @param __attr 条件变量属性指针// @return 0 成功,-1 失败,设置errnointpthread_condattr_init(pthread_condattr_t *__attr)// 获取条件变量属性中的时钟特性// @param __attr 条件变量属性指针// @param __clock_id 时钟特性指针// @return 0 成功,-1 失败,设置errnointpthread_condattr_getclock(constpthread_condattr_t * __restrict __attr,  __clockid_t *__restrict __clock_id)// 设置条件变量属性中的时钟特性// @param __attr 条件变量属性指针// @param __clock_id 时钟特性// @return 0 成功,-1 失败,设置errnointpthread_condattr_setclock(pthread_condattr_t *__attr, __clockid_t __clock_id)

对于条件变量属性时钟特性配置,支持以下几种。

  • CLOCK_REALTIME:使用实时时钟,会随着系统时间变化而变化(修改系统时间会导致条件变量超时变化,不建议使用)
  • CLOCK_MONOTONIC:使用单调时钟,不会因为系统时间变化而变化。

互斥量、条件变量应用示例

关于互斥量、条件变量应用示例如下。

////////////////////////////////////////////////////////////////////////////////  (c) copyright 2025-by Persion Inc.  //  All Rights Reserved////  Name://      main.c////  Purpose://      Linux C线程管理应用示例//// Author://      @公众号:<嵌入式技术总结>//// Revision History://      /////////////////////////////////////////////////////////////////////////////#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<errno.h>#include<unistd.h>#include<sys/time.h>#include<time.h>staticvolatileint g_i = 0;staticpthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;staticpthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;// 互斥量的应用void *thread_mutex_process(void *arg){for (int i = 0; i < 1000; i++)    {        pthread_mutex_lock(&g_mutex);        g_i++;        pthread_mutex_unlock(&g_mutex);    }// 退出线程,返回结果值// 此处强制转换为指针作为返回值    pthread_exit((int *)g_i);}// 条件变量的释放void *thread_condition_tx(void *arg){// 延时等待确保接收线程启动完成    usleep(100000);// 发送10个信号量for (int i = 0; i < 10; i++)    {        pthread_cond_signal(&g_cond);        usleep(500000);    }    pthread_exit(NULL);}// 条件变量的接收void *thread_condition_rx(void *arg){structtimespects;int timeout_count = 0;int rx_count = 0;while(1) {        clock_gettime(CLOCK_MONOTONIC, &ts);        ts.tv_sec += 1;        pthread_mutex_lock(&g_mutex);int status = pthread_cond_timedwait(&g_cond, &g_mutex, &ts);        pthread_mutex_unlock(&g_mutex);if(status == 0) {            rx_count++;printf("thread_condition_rx:%d\n", rx_count);        } elseif(status == ETIMEDOUT) {            timeout_count++;printf("thread_condition_rx timeout: %d\n", timeout_count);        } else {printf("thread_condition_rx error: %d\n", status);        }    }}intmain(int argc, char *argv[]){pthread_t tid[10];pthread_mutexattr_t mutex_attr;    pthread_mutexattr_init(&mutex_attr);    pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_NORMAL);    pthread_mutex_init(&g_mutex, &mutex_attr);// 创建线程for (int i = 0; i < 10; i++) {if (pthread_create(&tid[i], NULL, thread_mutex_process, NULL) != 0)        {printf("pthread_create error\n");exit(-1);        }    }// 等待所有线程完成for (int i = 0; i < 10; i++){        pthread_join(tid[i], NULL);    }printf("result g_i: %d\n", g_i);// 创建条件变量和应用pthread_condattr_t cond_attr;    pthread_condattr_init(&cond_attr);    pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);    pthread_cond_init(&g_cond, &cond_attr);pthread_t tx_tid, rx_tid;    pthread_create(&tx_tid, NULL, thread_condition_tx, NULL);    pthread_create(&rx_tid, NULL, thread_condition_rx, NULL);    pthread_join(tx_tid, NULL);    pthread_join(rx_tid, NULL);// 销毁条件变量和互斥锁    pthread_cond_destroy(&g_cond);    pthread_mutex_destroy(&g_mutex);return0;}

关于上述应用示例,执行的结果如下。

总结说明

互斥量提供了一种线程安全的数据访问方式,通过使用互斥量,可以避免数据竞争,从而保证程序的正确性和安全性。

条件变量,则提供了一个线程间同步机制,可以确保在条件变量满足时,线程才被唤醒执行,其它时间被堵塞而不占用CPU资源。

条件变量和互斥量是多线程编程的基础,这里主要从Linux C接口应用部分阐述相关接口的功能和应用,对于理解C标准库中的线斥量和条件变量接口也有一定帮助,可以互相印证提高。

最新文章

随机文章