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