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,头文件拷贝到项目就能直接用。

相关推荐
祈安_3 天前
C语言内存函数
c语言·后端
norlan_jame4 天前
C-PHY与D-PHY差异
c语言·开发语言
czy87874754 天前
除了结构体之外,C语言中还有哪些其他方式可以模拟C++的面向对象编程特性
c语言
m0_531237174 天前
C语言-数组练习进阶
c语言·开发语言·算法
Z9fish4 天前
sse哈工大C语言编程练习23
c语言·数据结构·算法
代码无bug抓狂人4 天前
C语言之单词方阵——深搜(很好的深搜例题)
c语言·开发语言·算法·深度优先
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习
枫叶丹45 天前
【Qt开发】Qt界面优化(七)-> Qt样式表(QSS) 样式属性
c语言·开发语言·c++·qt
with-the-flow5 天前
从数学底层的底层原理来讲 random 的函数是怎么实现的
c语言·python·算法
Sunsets_Red5 天前
P8277 [USACO22OPEN] Up Down Subsequence P 题解
c语言·c++·算法·c#·学习方法·洛谷·信息学竞赛