是从mysq里面抓出来的,只抓了一部分,主要是线程间通信,是用windows模拟linux,方便多线程的开发
#ifndef TP_OS_H #define TP_OS_H #ifdef __cplusplus #define EXTERNC extern "C" extern "C" { #else #define EXTERNC #endif /* __cplusplus */ #ifdef WIN32 #ifndef _WIN32_WINNT # define _WIN32_WINNT 0x500 #endif #include <process.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <string.h> #include <errno.h> #include <WinNT.h> #define bzero(A,B) memset((A),0,(B)) #define ETIMEDOUT 145 // Win32 doesn't have this #define sleep(x) Sleep(x*1000) typedef unsigned int uint32; typedef unsigned char uchar; /* Short for unsigned char */ typedef unsigned int uint; typedef CRITICAL_SECTION pthread_mutex_t; typedef HANDLE pthread_t; typedef struct thread_attr { DWORD dwStackSize ; DWORD dwCreatingFlag ; int priority ; } pthread_attr_t ; typedef struct { int dummy; } pthread_condattr_t; /* Implementation of posix conditions */ typedef struct st_pthread_link { DWORD thread_id; struct st_pthread_link *next; } pthread_link; typedef struct { uint32 waiting; CRITICAL_SECTION lock_waiting; enum { SIGNAL= 0, BROADCAST= 1, MAX_EVENTS= 2 } EVENTS; HANDLE events[MAX_EVENTS]; HANDLE broadcast_block_event; } pthread_cond_t; typedef int pthread_mutexattr_t; #define pthread_handler_t EXTERNC void * __cdecl typedef void * (__cdecl *pthread_handler)(void *); /* Struct and macros to be used in combination with the windows implementation of pthread_cond_timedwait */ /* Declare a union to make sure FILETIME is properly aligned so it can be used directly as a 64 bit value. The value stored is in 100ns units. */ union ft64 { FILETIME ft; __int64 i64; }; struct timespec { union ft64 tv; /* The max timeout value in millisecond for pthread_cond_timedwait */ long max_timeout_msec; }; #define set_timespec(ABSTIME,SEC) { / GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); / (ABSTIME).tv.i64+= (__int64)(SEC)*10000000; / (ABSTIME).max_timeout_msec= (long)((SEC)*1000); / } #define set_timespec_nsec(ABSTIME,NSEC) { / GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); / (ABSTIME).tv.i64+= (__int64)(NSEC)/100; / (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); / } int win_pthread_setspecific(void *a,void *b,uint length); int pthread_dummy(int ret); #define pthread_key(T,V) __declspec(thread) T V #define pthread_key_create(A,B) pthread_dummy(0) #define pthread_key_delete(A) pthread_dummy(0) #define pthread_getspecific(A) (&(A)) #define my_pthread_getspecific(T,A) (&(A)) #define my_pthread_getspecific_ptr(T,V) (V) #define my_pthread_setspecific_ptr(T,V) ((T)=(V),0) #define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A)) #define pthread_equal(A,B) ((A) == (B)) #define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0) #define pthread_mutex_lock(A) (EnterCriticalSection(A),0) #define pthread_mutex_unlock(A) LeaveCriticalSection(A) #define pthread_mutex_destroy(A) DeleteCriticalSection(A) //#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH) int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,struct timespec *abstime); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_destroy(pthread_cond_t *cond); int pthread_attr_init(pthread_attr_t *connect_att); int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); int pthread_attr_setprio(pthread_attr_t *connect_att,int priority); int pthread_attr_destroy(pthread_attr_t *connect_att); int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *); struct tm *localtime_r(const time_t *timep,struct tm *tmp); struct tm *gmtime_r(const time_t *timep,struct tm *tmp); void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) #define pthread_join(A,B) (WaitForSingleObject((A), INFINITE) != WAIT_OBJECT_0) #else #include <pthread.h> #include <unistd.h> #define pthread_key(T,V) pthread_key_t V #endif #ifdef __cplusplus } #endif #endif
#include "tp_os.h" #ifdef WIN32 #include <time.h> #include <sys/timeb.h> #include <WinBase.h> int pthread_create(pthread_t *thread_id, pthread_attr_t *attr, pthread_handler func, void *param) { HANDLE hThread; hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) func, //attr->dwStackSize ? attr->dwStackSize : 65535, param); *thread_id = hThread; if (hThread == (HANDLE) -1) { int error=errno; printf("create thread error"); return(error ? error : -1); } //SetThreadPriority(hThread, attr->priority); return(0); } void pthread_exit(void *a) { _endthread(); } int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { cond->waiting= 0; InitializeCriticalSection(&cond->lock_waiting); cond->events[SIGNAL]= CreateEvent(NULL, /* no security */ FALSE, /* auto-reset event */ FALSE, /* non-signaled initially */ NULL); /* unnamed */ /* Create a manual-reset event. */ cond->events[BROADCAST]= CreateEvent(NULL, /* no security */ TRUE, /* manual-reset */ FALSE, /* non-signaled initially */ NULL); /* unnamed */ cond->broadcast_block_event= CreateEvent(NULL, /* no security */ TRUE, /* manual-reset */ TRUE, /* signaled initially */ NULL); /* unnamed */ if( cond->events[SIGNAL] == NULL || cond->events[BROADCAST] == NULL || cond->broadcast_block_event == NULL ) return ENOMEM; return 0; } int pthread_cond_destroy(pthread_cond_t *cond) { DeleteCriticalSection(&cond->lock_waiting); if (CloseHandle(cond->events[SIGNAL]) == 0 || CloseHandle(cond->events[BROADCAST]) == 0 || CloseHandle(cond->broadcast_block_event) == 0) return EINVAL; return 0; } int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { return pthread_cond_timedwait(cond,mutex,NULL); } int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime) { int result; long timeout; union ft64 now; if( abstime != NULL ) { GetSystemTimeAsFileTime(&now.ft); /* Calculate time left to abstime - subtract start time from current time(values are in 100ns units) - convert to millisec by dividing with 10000 */ timeout= (long)((abstime->tv.i64 - now.i64) / 10000); /* Don't allow the timeout to be negative */ if (timeout < 0) timeout= 0L; /* Make sure the calucated timeout does not exceed original timeout value which could cause "wait for ever" if system time changes */ if (timeout > abstime->max_timeout_msec) timeout= abstime->max_timeout_msec; } else { /* No time specified; don't expire */ timeout= INFINITE; } /* Block access if previous broadcast hasn't finished. This is just for safety and should normally not affect the total time spent in this function. */ WaitForSingleObject(cond->broadcast_block_event, INFINITE); EnterCriticalSection(&cond->lock_waiting); cond->waiting++; LeaveCriticalSection(&cond->lock_waiting); LeaveCriticalSection(mutex); result= WaitForMultipleObjects(2, cond->events, FALSE, timeout); EnterCriticalSection(&cond->lock_waiting); cond->waiting--; if (cond->waiting == 0) { /* We're the last waiter to be notified or to stop waiting, so reset the manual event. */ /* Close broadcast gate */ ResetEvent(cond->events[BROADCAST]); /* Open block gate */ SetEvent(cond->broadcast_block_event); } LeaveCriticalSection(&cond->lock_waiting); EnterCriticalSection(mutex); return result == WAIT_TIMEOUT ? ETIMEDOUT : 0; } int pthread_cond_signal(pthread_cond_t *cond) { EnterCriticalSection(&cond->lock_waiting); if(cond->waiting > 0) SetEvent(cond->events[SIGNAL]); LeaveCriticalSection(&cond->lock_waiting); return 0; } int pthread_cond_broadcast(pthread_cond_t *cond) { EnterCriticalSection(&cond->lock_waiting); /* The mutex protect us from broadcasting if there isn't any thread waiting to open the block gate after this call has closed it. */ if(cond->waiting > 0) { /* Close block gate */ ResetEvent(cond->broadcast_block_event); /* Open broadcast gate */ SetEvent(cond->events[BROADCAST]); } LeaveCriticalSection(&cond->lock_waiting); return 0; } int pthread_attr_init(pthread_attr_t *connect_att) { connect_att->dwStackSize = 0; connect_att->dwCreatingFlag = 0; connect_att->priority = 0; return 0; } int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack) { connect_att->dwStackSize=stack; return 0; } int pthread_attr_setprio(pthread_attr_t *connect_att,int priority) { connect_att->priority=priority; return 0; } int pthread_attr_destroy(pthread_attr_t *connect_att) { bzero((uchar*) connect_att,sizeof(*connect_att)); return 0; } int win_pthread_setspecific(void *a,void *b,uint length) { memcpy(a,b,length); return 0; } /**************************************************************************** ** Fix localtime_r() to be a bit safer ****************************************************************************/ struct tm *localtime_r(const time_t *timep,struct tm *tmp) { if (*timep == (time_t) -1) /* This will crash win32 */ { bzero(tmp,sizeof(*tmp)); } else { struct tm *res=localtime(timep); if (!res) /* Wrong date */ { bzero(tmp,sizeof(*tmp)); /* Keep things safe */ return 0; } *tmp= *res; } return tmp; } int pthread_dummy(int ret) { return ret; } #endif
//一个例子 #include "tp_os.h" #include "string.h" #include <stdio.h> typedef enum { P_INIT, P_OK, P_ERROR } PC_State; typedef struct PC_Index { pthread_t* childTid; int childCount; volatile int workCount; pthread_mutex_t mutex; pthread_cond_t c_index; pthread_cond_t c_commit; PC_State state; PC_State* childState; } PC_Index; typedef struct PC_Para { PC_Index *index; int childId; char createIndexPara[10]; } PC_Para; int createIndex(PC_Para *para) { sleep(5); //控制执行错的线程在执行对的之前,还是之后 if (para->index->state == P_OK) { printf("/n create index %s", (char*)para->createIndexPara); return 1; } else { printf("/n create index error %s", (char*)para->createIndexPara); return 0; } } int createIndexError(void *para) { sleep(3); printf("/n*** create index %s error", (char*)para); return 0; } int commitOrRollback(PC_Para *para) { if (para->index->state == P_OK) printf("/n commit %s", (char*)para->createIndexPara); else printf("/n rollback %s", (char*)para->createIndexPara); return 1; } void * do_work(void *par) { PC_Para *para = (PC_Para*)par; PC_Index* index = para->index; if ( !createIndex(para)) { pthread_mutex_lock( &(index->mutex)); index->childState[para->childId] = P_ERROR; index->state = P_ERROR; pthread_cond_signal(&index->c_index); pthread_mutex_unlock( &(index->mutex)); //printf("/nrollback immediately %s", para->createIndexPara); //return; }else { pthread_mutex_lock( &(index->mutex)); index->childState[para->childId] = P_OK; index->workCount--; if (index->workCount <= 0) pthread_cond_signal(&index->c_index); pthread_mutex_unlock( &(index->mutex)); } pthread_mutex_lock( &(index->mutex)); pthread_cond_wait( &(index->c_commit), &(index->mutex) ); index->workCount--; pthread_mutex_unlock( &(index->mutex)); commitOrRollback(para); } void * do_work_error(void *par) { PC_Para *para = (PC_Para*)par; PC_Index* index = para->index; if ( !createIndexError(para->createIndexPara)) { pthread_mutex_lock( &(index->mutex)); index->childState[para->childId] = P_ERROR; index->state = P_ERROR; pthread_cond_signal(&index->c_index); pthread_mutex_unlock( &(index->mutex)); //printf("/nrollback immediately %s", para->createIndexPara); }else { pthread_mutex_lock( &(index->mutex)); index->childState[para->childId] = P_OK; index->workCount--; if (index->workCount <= 0) pthread_cond_signal(&index->c_index); pthread_mutex_unlock( &(index->mutex)); } pthread_mutex_lock( &(index->mutex)); pthread_cond_wait( &(index->c_commit), &(index->mutex) ); index->workCount--; pthread_mutex_unlock( &(index->mutex)); commitOrRollback(para); } void main() { PC_Para* para; PC_Index index; int i, runcount; int indexCount = 40; printf("/nindex start/n"); pthread_mutex_init( &(index.mutex), NULL ); pthread_cond_init( &(index.c_commit), NULL ); pthread_cond_init( &(index.c_index), NULL ); index.workCount = indexCount; index.childCount = indexCount; index.state = P_OK; para = (PC_Para*)malloc(indexCount * sizeof(PC_Para)); index.childState = (PC_State*)malloc(indexCount * sizeof(PC_State)); index.childTid = (pthread_t*)malloc(indexCount * sizeof(pthread_t)); for(i=0; i<indexCount; i++) { para[i].childId = i; para[i].index = &index; memset(para[i].createIndexPara, 0, 10); sprintf(para[i].createIndexPara, "%d", i); index.childState[i] = P_INIT; } pthread_mutex_lock( &(index.mutex)); for(i=0; i<indexCount; i++) { if (i == indexCount -1) { pthread_create(&(index.childTid[i]), NULL, do_work_error, (void*)(¶[i])); } else //控制是否出错 if (pthread_create(&(index.childTid[i]), NULL, do_work, (void*)(¶[i]))) { printf("create thread error"); exit(0); } } runcount = 0; while(index.workCount > 0 && index.state == P_OK) { pthread_cond_wait( &index.c_index, &index.mutex ); runcount++; } printf("/n runcount1: %d", runcount); pthread_mutex_unlock( &(index.mutex)); for(i=0; i<indexCount; i++) { if (index.childState[i] == P_ERROR) { index.state = P_ERROR; printf("/nchild %d,error", i); } } index.workCount = indexCount; runcount = 0; while(index.workCount > 0) { runcount++; pthread_mutex_lock( &(index.mutex)); pthread_cond_signal(&(index.c_commit)); pthread_mutex_unlock( &(index.mutex)); } printf("/n runcount2: %d", runcount); sleep(1); printf("/nindex end/n"); }