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

相关推荐
海上Bruce4 小时前
C primer plus (第六版)第十二章 编程练习第3题
c语言
SundayBear4 小时前
零基础入门MQTT协议
c语言·单片机
我能坚持多久4 小时前
D16—C语言内功之数据在内存中的存储
c语言·开发语言
福楠5 小时前
C++ STL | map、multimap
c语言·开发语言·数据结构·c++·算法
极客小云5 小时前
【基于 PyQt6 的红外与可见光图像配准工具开发实战】
c语言·python·yolo·目标检测
Ethernet_Comm6 小时前
从 C 转向 C++ 的过程
c语言·开发语言·c++
爱编码的小八嘎9 小时前
c语言对话-1.auto_ptr再回忆
c语言
嵌入小生0079 小时前
基于Linux系统下的C语言程序错误及常见内存问题调试方法教程(嵌入式-Linux-C语言)
linux·c语言·开发语言·嵌入式·小白·内存管理调试·程序错误调试
W_a_i_T10 小时前
【Coding日记】菜鸟编程C语言100例——第一题
c语言·学习·编程思维·菜鸟编程
程序员_大白10 小时前
区块链部署与运维,零基础入门到精通,收藏这篇就够了
运维·c语言·开发语言·区块链