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 SRWLOCK RWMutex; 
/**
 * @brief 初始化读写锁
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return void无返回
 */
#define rwmutex_create(mtx) InitializeSRWLock(mtx)
#else
#include <pthread.h>
typedef pthread_rwlock_t RWMutex; 
#define rwmutex_create(mtx) pthread_rwlock_init(mtx,0)
#endif

二、完整代码

rwmutex.h

c 复制代码
/***********************************************************************************************************************
 * Copyright (C): 2025-2025, codeofcc. All rights reserved.
 * @file : sem.h
 * @brief : 通用线程类封装,在Windows上使用win32api,其他平台使用pthread。
 * @author : codeofcc
 * @email :
 * @version : 1.0.0
 * @date : 2025/6/6 16:34:27
 ******************************************************************************************************************/
#ifndef RWMUTEX_H
#define RWMUTEX_H
#ifdef _WIN32
#ifndef _WIN32_WINNT
// 使用mingw编译时需要此定义。
#define _WIN32_WINNT 0x0600
#endif
#include <windows.h>
/// @brief 读写锁
typedef SRWLOCK RWMutex; 
/**
 * @brief 初始化读写锁
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return void无返回
 */
#define rwmutex_create(mtx) InitializeSRWLock(mtx)
/**
 * @brief 销毁读写锁
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return void无返回
 */
#define rwmutex_destroy(mtx) 
/**
 * @brief 获取写锁,阻塞直到获取锁为止
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return void无返回
 */
#define rwmutex_lock(mtx)  AcquireSRWLockExclusive(mtx)
/**
 * @brief 尝试获取写锁,不阻塞
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return BOOL 成功返回1,失败返回0
 */
#define rwmutex_trylock(mtx)  TryAcquireSRWLockExclusive(mtx)
/**
 * @brief 释放写锁
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return void无返回
 */
#define rwmutex_unlock(mtx)  ReleaseSRWLockExclusive(mtx)
/**
 * @brief 获取读锁,阻塞直到获取锁为止
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return void无返回
 */
#define rwmutex_read_lock(mtx)  AcquireSRWLockShared(mtx)
/**
 * @brief 尝试获取读锁,不阻塞
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return BOOL 成功返回1,失败返回0
 */
#define rwmutex_read_trylock(mtx)  TryAcquireSRWLockShared(mtx)
/**
 * @brief 释放读锁
 * @param mtx 读写锁变量,类型为RWMutex*
 * @return void无返回
 */
#define rwmutex_read_unlock(mtx)  ReleaseSRWLockShared(mtx)
#else
#include <pthread.h>
typedef pthread_rwlock_t RWMutex; 
#define rwmutex_create(mtx) pthread_rwlock_init(mtx,0)
#define rwmutex_destroy(mtx) pthread_rwlock_destroy(mtx)
#define rwmutex_lock(mtx)  pthread_rwlock_wrlock(mtx)
#define rwmutex_trylock(mtx)  pthread_rwlock_trywrlock(mtx)==0
#define rwmutex_unlock(mtx)  pthread_rwlock_unlock(mtx)
#define rwmutex_read_lock(mtx)  pthread_rwlock_rdlock(mtx)
#define rwmutex_read_trylock(mtx)  pthread_rwlock_tryrdlock(mtx)==0
#define rwmutex_read_unlock(mtx)  pthread_rwlock_unlock(mtx)
#endif
#endif

三、使用示例

1、多线程读写数据

c 复制代码
#include <string.h>
#include"rwmutex.h"
#include"thread.h"
char buffer[512] = {0};
TINT task(void *arg)
{
	RWMutex *mutex = (RWMutex *)arg;
	while (1)
	{
	  //进入读锁
		rwmutex_read_lock(mutex);
		// 可以多个线程同时读取数据
		printf("%s", buffer);
		if (strcmp(buffer, "hello word!") == 0)
		{
			rwmutex_read_unlock(mutex);
			return 0;
		}
		rwmutex_read_unlock(mutex);
		thread_sleep(30);
	}
	return 0;
}

int main()
{
	RWMutex mutex;
	rwmutex_create(&mutex);
	rwmutex_lock(&mutex);

	Thread thread;
	// 开启线程1
	thread_create(&thread, task, (void *)&mutex);
	thread_detach(thread);
	// 开启线程2
	thread_create(&thread, task, (void *)&mutex);
	thread_detach(thread);

	thread_sleep(1000);
	//进入写锁
	rwmutex_lock(&mutex);
	// 写入数据
	strcat(buffer, "hello word!");
	rwmutex_unlock(&mutex);

	// 销毁资源
	rwmutex_destroy(&mutex);
	printf("rwmutex_test0 passed\n");
}

总结

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

相关推荐
风指引着方向3 小时前
图编译优化全链路:CANN graph-engine 仓库技术拆解
c语言
C++ 老炮儿的技术栈3 小时前
VS2015 + Qt 实现图形化Hello World(详细步骤)
c语言·开发语言·c++·windows·qt
Once_day3 小时前
C++之《Effective C++》读书总结(4)
c语言·c++·effective c++
晓13133 小时前
第七章 【C语言篇:文件】 文件全面解析
linux·c语言·开发语言
梵刹古音3 小时前
【C语言】 指针基础与定义
c语言·开发语言·算法
杜子不疼.4 小时前
Ascend_C自定义算子开发
c语言·开发语言
小乔的编程内容分享站4 小时前
C语言笔记之函数
c语言·笔记
杜子不疼.5 小时前
基于ATVC模板库的Ascend C Vector算子快速开发指南
c语言·开发语言·mfc
C++ 老炮儿的技术栈5 小时前
Qt Creator中不写代如何设置 QLabel的颜色
c语言·开发语言·c++·qt·算法
艾莉丝努力练剑5 小时前
【Linux:文件】基础IO
linux·运维·c语言·c++·人工智能·io·文件