创建tthread中的thread和mutex

This commit is contained in:
zzy 2023-10-23 13:21:02 +08:00
parent 2a2ae674e6
commit 73847e5708
4 changed files with 164 additions and 10 deletions

4
.gitignore vendored
View File

@ -9,4 +9,6 @@
!test/client/client.c
!test/client/CMakeLists.txt
!test/server/server.c
!test/server/CMakeLists.txt
!test/server/CMakeLists.txt
!test/thread/thread.c
!test/thread/CMakeLists.txt

View File

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.22.1)
project(thread)
set(EXECUTABLE_OUTPUT_PATH ../)
set(CMAKE_C_STANDARD 99)
set(SRC_FILE thread.c)
add_executable(${PROJECT_NAME} ${SRC_FILE})
if(WIN32)
target_link_libraries(${PROJECT_NAME} wsock32 ws2_32)
endif()
# cmake ..
# cmake --build .

39
test/thread/thread.c Normal file
View File

@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
#include "../../tthread.h"
MUTEX mutex;
void work(void* arg) {
int* num = (int*)arg;
for (int i = 0; i < 100; i++) {
thread_mutex_lock(mutex);
printf("%d => %d\n", 1, (*num)++);
thread_mutex_unlock(mutex);
}
}
int main()
{
int res;
TID tid;
int num = 0;
if (thread_mutex_init(&mutex) != 0) {
return -1;
}
if (thread_create(&tid, work, &num) != 0) {
return -2;
}
for (int i = 0; i < 100; i++) {
thread_mutex_lock(mutex);
printf("%d => %d\n", 0, num++);
thread_mutex_unlock(mutex);
}
res = thread_join(tid);
if (res != 0) {
//res = GetLastError();
return res;
}
return 0;
}

116
tthread.h
View File

@ -3,15 +3,21 @@
#include "sysenv.h"
#if _OS_WIN
#include <windows.h>
#define TID LPDWORD
//#include <handleapi.h>
//#include <synchapi.h>
//#include <processthreadsapi.h>
//#define INFINITE 0xFFFFFFFF // Infinite timeout
//#define WAIT_FAILED ((DWORD)0xFFFFFFFF)
//#include <WinBase.h>
#include <Windows.h>
typedef DWORD TID;
typedef HANDLE MUTEX;
typedef HANDLE COND;
#elif _OS_LINUX
#include <unistd.h>
#include <pthread.h>
#include <strings.h>
#define TID pthread_t
#define MUTEX pthread_mutex_t
#define COND pthread_cond_t
#else
#error "Not Supported Operator System"
#endif
@ -20,13 +26,105 @@
extern "C" {
#endif
enum {
ERR_THREAD_SUCCESS,
static inline void tthread_create(TID* tid,void(*thread_func)(void*), void* data) {
ERR_THREAD_CREATE,
ERR_THREAD_JOIN,
ERR_THREAD_WIN_CLOSE_HANDLE,
ERR_THREAD_WIN_OPEN_THREAD,
ERR_THREAD_MUTEX_INIT,
ERR_THREAD_MUTEX_DESTROY,
ERR_THREAD_MUTEX_LOCK,
ERR_THREAD_MUTEX_UNLOCK,
ERR_THREAD_COND_INIT,
ERR_THREAD_COND_DESTROY,
ERR_THREAD_COND_SINGAL,
ERR_THREAD_COND_BROADCAST,
ERR_THREAD_COND_WAIT,
ERR_THREAD_COND_TIMEDWAIT,
ERR_THREAD_ENUM_END
};
static inline int thread_create(TID* tid, void(*start_routine)(void*), void* arg);
static inline void thread_exit(void);
static inline int thread_join(TID tid);
static inline int thread_mutex_init(MUTEX* mutex);
static inline int thread_mutex_destory(MUTEX mutex);
static inline int thread_mutex_lock(MUTEX mutex);
static inline int thread_mutex_unlock(MUTEX mutex);
static inline int thread_create(TID* tid, void(*start_routine)(void*), void* arg) {
#if _OS_WIN
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, tid);
HANDLE h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, tid);
if (h == NULL) { return ERR_THREAD_CREATE; }
if (!CloseHandle(h)) { return ERR_THREAD_WIN_CLOSE_HANDLE; }
#elif _OS_LINUX
pthread_create(tid, 0, (void*(*)(void*))thread_func, data);
if (pthread_create(tid, NULL, start_routine, arg) != 0) { return ERR_THREAD_CREATE; }
#endif
return ERR_THREAD_SUCCESS;
}
static inline void thread_exit(void) {
#if _OS_WIN
ThreadExit(0);
#elif _OS_LINUX
pthread_exit(NULL);
#endif
}
static inline int thread_join(TID tid) {
#if _OS_WIN
HANDLE h = OpenThread(THREAD_ALL_ACCESS, 0, tid);
if (h == NULL) { return ERR_THREAD_WIN_OPEN_THREAD; }
if (WaitForSingleObject(h, INFINITE) == WAIT_FAILED) { return ERR_THREAD_JOIN; }
if (!CloseHandle(h)) { return ERR_THREAD_WIN_CLOSE_HANDLE; }
#elif _OS_LINUX
if (pthread_join(tid, NULL) != 0) { return ERR_THREAD_JOIN; }
#endif
return ERR_THREAD_SUCCESS;
}
// mutex part
static inline int thread_mutex_init(MUTEX* mutex) {
#if _OS_WIN
*mutex = CreateMutex(NULL, FALSE, NULL);
if (*mutex == NULL) { return ERR_THREAD_MUTEX_INIT; }
#elif _OS_LINUX
if (pthread_mutex_init() != 0) { return ERR_THREAD_MUTEX_INIT; }
#endif
return ERR_THREAD_SUCCESS;
}
static inline int thread_mutex_destory(MUTEX mutex) {
#if _OS_WIN
if (!CloseHandle(mutex)) { return ERR_THREAD_MUTEX_DESTROY; }
#elif _OS_LINUX
if (pthread_mutex_destroy(mutex) != 0) { return ERR_THREAD_MUTEX_DESTROY; }
#endif
ERR_THREAD_SUCCESS;
}
static inline int thread_mutex_lock(MUTEX mutex) {
#if _OS_WIN
if (WaitForSingleObject(mutex, INFINITE) == WAIT_FAILED) { return ERR_THREAD_MUTEX_LOCK; }
#elif _OS_LINUX
if (pthread_mutex_lock(mutex) != 0) { return ERR_THREAD_MUTEX_LOCK; }
#endif
return ERR_THREAD_SUCCESS;
}
static inline int thread_mutex_unlock(MUTEX mutex) {
#if _OS_WIN
ReleaseMutex(mutex);
#elif _OS_LINUX
if (pthread_mutex_unlock(mutex) != 0) { return ERR_THREAD_MUTEX_UNLOCK; }
#endif
return ERR_THREAD_SUCCESS;
}
#ifdef __cplusplus