c语言 封装跨平台条件变量头文件

c语言线程类

第一章 跨平台线程
第二章 跨平台互斥锁
第三章 跨平台信号量
第四章 跨平台条件变量(本章)
第五章 跨平台读写锁
第六章 整合版


文章目录


前言

c语言的标准库是没有线程类的,不同平台的使用方式都有所不同,Windows上通常用win32 api,其他平台则是pthread。当想要写通用的跨平台代码时,涉及到多线程以及线程安全操作就会很不方便。笔者以前写过跨平台线程类的封装,自定义了一套接口和实现,能使用但是还不是最方便的。比如写项目的时候还是需要在cmakelist中加入.c文件的。本文的做法是进一步简化,只需要一个头文件就能实现跨平台的信号量封装。


一、如何实现?

我们其实只需要通过宏定义一套接口就可以了,而不需要自定义线程对象以及函数和实现。

定义一个宏方法在Windows上宏展开是调用win32 api,其他平台则是调用pthread。

如下:

cpp 复制代码
#ifdef _WIN32
#ifndef _WIN32_WINNT
//使用mingw编译时需要此定义。
#define _WIN32_WINNT 0x0600
#endif
#include <windows.h>
/// @brief 条件变量
typedef CONDITION_VARIABLE Cond;
/**
 * @brief 创建条件变量
 * @param cond 条件变量,类型为Cond*
 * @return 0成功,其他值失败
 */
#define cond_create(cond) 1==0,InitializeConditionVariable(cond)
#else
#include <pthread.h>
#include <sys/time.h>
#include <stdint.h>
typedef pthread_cond_t Cond;
#define cond_create(cond) pthread_cond_init(cond,0)
#endif

二、完整代码

cond.h

c 复制代码
/***********************************************************************************************************************
 * Copyright (C): 2025-2025, codeofcc. All rights reserved.
 * @file : thread.h
 * @brief : 通用线程类封装,在Windows上使用win32api,其他平台使用pthread。
 * @author : codeofcc
 * @email : 
 * @version : 1.0.0
 * @date : 2025/6/6 16:34:27
******************************************************************************************************************/
#ifndef COND_H
#define COND_H
#ifdef _WIN32
#ifndef _WIN32_WINNT
//使用mingw编译时需要此定义。
#define _WIN32_WINNT 0x0600
#endif
#include <windows.h>
/// @brief 条件变量
typedef CONDITION_VARIABLE Cond;
/**
 * @brief 创建条件变量
 * @param cond 条件变量,类型为Cond*
 * @return 0成功,其他值失败
 */
#define cond_create(cond) 1==0,InitializeConditionVariable(cond)
/**
 * @brief 销毁条件变量
 * @param cond 条件变量,类型为Cond*
 * @return void无返回
 */
#define cond_destroy(cond) WakeAllConditionVariable(cond)
/**
 * @brief 等待条件变量
 * @param cond 条件变量,类型为Cond*
 * @param mtx 互斥变量,类型为Mutex*
 * @return 0成功,其他值失败
 */
#define cond_wait(cond, mtx) SleepConditionVariableCS(cond, mtx, INFINITE)==0
/**
 * @brief 等待条件变量,带超时时间
 * @param cond 条件变量,类型为Cond*
 * @param mtx 互斥变量,类型为Mutex*
 * @param ms 超时时间,相对时间,单位毫秒,类型为int
 * @param ret 返回值,0成功,其他值失败。类型为int*
 * @return void无返回
 */
#define cond_wait_time(cond, mtx,ms,ret) *(ret)=SleepConditionVariableCS(cond, mtx, ms)==0
/**
 * @brief 释放条件变量
 * @param cond 条件变量,类型为Cond*
 * @return void无返回
 */
#define cond_post(cond) WakeConditionVariable(cond)
/**
 * @brief 释放条件变量,广播
 * @param cond 条件变量,类型为Cond*
 * @return void无返回
 */
#define cond_brocast(cond) WakeAllConditionVariable(cond)
#else
#include <pthread.h>
#include <sys/time.h>
#include <stdint.h>
typedef pthread_cond_t Cond;
#define cond_create(cond) pthread_cond_init(cond,0)
#define cond_destroy(cond) pthread_cond_destroy(cond)
#define cond_wait(cond, mtx) pthread_cond_wait(cond, mtx)
#define cond_wait_time(cond, mtx,ms,ret)  { struct timespec time;clock_gettime(CLOCK_REALTIME, &time); time.tv_sec += (ms / 1000);time.tv_nsec+=((ms % 1000)) * 1000000; *(ret)=pthread_cond_timedwait(cond, mtx,&time);}
#define cond_post(cond) pthread_cond_signal(cond)
#define cond_brocast(cond) pthread_cond_broadcast(cond)
#endif
#endif

三、使用示例

1、多线程等待

c 复制代码
 #include "cond.h"
TINT task(void *arg)
{
	Cond *cond = (Cond *)arg;
	//执行任务
	thread_sleep(500);
	//完成后通知
	cond_post(cond);
	return 0;
}

int main()
{
	int ret = 0;
	Cond cond;
	Mutex mtx;
	mutex_create(&mtx);
	ret = cond_create(&cond);
	if (ret != 0)
	{
		printf("cond_create error %d\n", ret);
		return -1;
	}
	//开启线程
	Thread thread;
	thread_create(&thread, task, (void *)&cond);
	thread_detach(thread);
	//等待任务
	mutex_lock(&mtx);
	cond_wait(&cond, &mtx);
	mutex_unlock(&mtx);
	//结束后销毁资源
	mutex_destroy(&mtx);
	cond_destroy(&cond);
}

2、超时等待

c 复制代码
#include "cond.h"
TINT task(void *arg)
{
	Cond *cond = (Cond *)arg;
	// 执行任务
	thread_sleep(500);
	// 完成后通知
	cond_post(cond);
	return 0;
}

int main()
{
	int ret = 0;
	Cond cond;
	Mutex mtx;
	mutex_create(&mtx);
	ret = cond_create(&cond);
	if (ret != 0)
	{
		printf("cond_create error %d\n", ret);
		return -1;
	}
	// 开启线程
	Thread thread;
	thread_create(&thread, task, (void *)&cond);
	thread_detach(thread);
	do
	{
		//执行其他操作避免阻塞
         ...
		// 等待任务,超时30毫秒
		mutex_lock(&mtx);
		cond_wait_time(&cond, &mtx, 30, &ret);
		mutex_unlock(&mtx);
	} while (!ret);
	// 结束后销毁资源
	mutex_destroy(&mtx);
	cond_destroy(&cond);
}

总结

以上就是今天要讲的内容,本文只是简单将不同平台的条件变量方法进行了一个整合,对函数的参数和返回值做了一个统一。由于在所有实现在头文件中,使用起来是很方便的,不需要额外编写makefile或cmakelist,头文件拷贝到项目就能直接用。

相关推荐
炸膛坦客14 小时前
单片机/C/C++八股:(二十六)IIC 专题(I²C)---- 上集
c语言·c++·单片机
程序员Rock21 小时前
上位机开发-MODBUS面试常见问题
c语言·c++·面试·职场和发展·上位机
blevoice1 天前
抖抖燃脂机单 AC6966B 主控调试踩坑:Type-C 整机供电喇叭无声排障
c语言·开发语言·单片机
小小晓.1 天前
C++小白记:C风格字符串和数组用法
c语言·开发语言·c++
深念Y1 天前
开发者如何清理和迁移C盘堆积的垃圾
c语言·开发语言
十月的皮皮1 天前
STM32从零到量产开发:四路继电器工业控制模块开发实战笔记(小白视角)
c语言·笔记·stm32·stm32cubemx·hal库
不正经学生1 天前
C 语言函数深入剖析(基础篇)—— 从零理解函数的每一个细节
c语言·开发语言·数据结构·算法·c#
天空'之城1 天前
C 语言工业级通用组件手写 10:字节序转换
c语言·字节序·大小端·嵌入式通信·工业级组件
C++ 老炮儿的技术栈2 天前
OpenCV 实现社保卡透视矫正:Hough 直线提取四角并转正证件图像
c语言·c++·人工智能·opencv·算法·计算机视觉·c
我叫洋洋2 天前
C ++ [ hello world ]
c语言·c++·算法