Files
2026-08-30 04:11:22 +08:00

126 lines
3.8 KiB
C

#ifndef INCLUDED_C_THREAD_H
#define INCLUDED_C_THREAD_H
#ifndef INCLUDED_C_TYPES_H
#include <c_Types.h>
#endif /*INCLUDED_C_TYPES_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef void* c_ThreadResult_t;
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#include <process.h>
typedef HANDLE c_Thread_t;
typedef DWORD c_ThreadId_t; // Windows 使用 DWORD 作为线程 ID
#define C_THREAD_FUNC_RETURN_TYPE unsigned __stdcall
#define C_THREAD_FUNC_RETURN_VTYPE unsigned
#else
#include <pthread.h>
typedef pthread_t c_Thread_t;
typedef unsigned long c_ThreadId_t; // POSIX 转换为数字 ID
#define C_THREAD_FUNC_RETURN_TYPE void*
#define C_THREAD_FUNC_RETURN_VTYPE C_THREAD_FUNC_RETURN_TYPE
#endif
// Universal thread creation signature
typedef C_THREAD_FUNC_RETURN_TYPE (*c_ThreadFn_t)(void*);
C_STATIC_FORCE_INLINE
c_bool_t c_Thread_Create(c_Thread_t* thread, c_ThreadFn_t func, void* arg) {
#if defined(_WIN32) || defined(_WIN64)
// *thread = CreateThread(NULL, 0, func, arg, 0, NULL);
// return (*thread != NULL);
*thread = (HANDLE)_beginthreadex(NULL, 0, (unsigned (__stdcall *)(void*))func, arg, 0, NULL);
return (*thread != NULL);
#else
return (pthread_create(thread, NULL, func, arg) == 0);
#endif
}
C_STATIC_FORCE_INLINE
void c_Thread_Join(c_Thread_t thread) {
#if defined(_WIN32) || defined(_WIN64)
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
#else
pthread_join(thread, NULL);
#endif
}
C_STATIC_FORCE_INLINE
void c_Thread_Sleep(unsigned int milliseconds) {
#if defined(_WIN32) || defined(_WIN64)
Sleep(milliseconds);
#else
usleep(milliseconds * 1000);
#endif
}
C_STATIC_FORCE_INLINE
c_ThreadId_t c_Thread_SelfId(void) {
#if defined(_WIN32) || defined(_WIN64)
return GetCurrentThreadId();
#else
return (c_ThreadId_t)pthread_self();
#endif
}
C_STATIC_FORCE_INLINE
c_bool_t c_Thread_Detach(c_Thread_t thread) {
#if defined(_WIN32) || defined(_WIN64)
// Windows 中,关闭线程句柄并不等于终止线程。
// 它只是减少内核对象的引用计数。线程运行结束时,内核对象会自动销毁。
// 这与 POSIX 的 detach 行为完全一致。
if (thread != NULL) {
return (CloseHandle(thread) != 0);
}
return C_FALSE;
#else
// POSIX 直接使用 pthread_detach
return (pthread_detach(thread) == 0);
#endif
}
C_STATIC_FORCE_INLINE
c_bool_t c_Thread_Equal(c_Thread_t t1, c_Thread_t t2) {
#if defined(_WIN32) || defined(_WIN64)
// Windows 下可以通过比较线程 ID 来判断是否为同一个线程
// 即使其中一个是 GetCurrentThread() 产生的伪句柄,GetThreadId 也能正确识别
return (GetThreadId(t1) == GetThreadId(t2));
#else
// POSIX 提供专用的比较函数
return (pthread_equal(t1, t2) != 0);
#endif
}
C_STATIC_FORCE_INLINE
c_bool_t c_Thread_JoinWithResult(c_Thread_t thread, c_ThreadResult_t* out_result) {
#if defined(_WIN32) || defined(_WIN64)
if (WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0) {
DWORD exit_code = 0;
if (GetExitCodeThread(thread, &exit_code)) {
if (out_result) {
// 将 DWORD 转换为指针类型输出
*out_result = (c_ThreadResult_t)(uintptr_t)exit_code;
}
CloseHandle(thread);
return C_TRUE;
}
}
CloseHandle(thread); // 即使失败也尝试关闭句柄
return C_FALSE;
#else
// POSIX 直接在 join 时传入指针变量的地址
return (pthread_join(thread, out_result) == 0);
#endif
}
#define c_Thread_Exit(x) return (C_THREAD_FUNC_RETURN_VTYPE)(x)
#define c_Thread_Fn(fn) C_THREAD_FUNC_RETURN_TYPE fn
#endif /*INCLUDED_C_THREAD_H*/