| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /************************************************************************
- * AUTHOR: NiuJiuRu
- * FILENAME: swthrd.c
- * DESCRIPTION: 线程操作
- * NOTE:
- * HISTORY:
- * 1, [2010-12-18] created by NiuJiuRu
- * 2, [2014-05-13] 修改"sw_thrd_delay()"函数, 当延时时间为负数时, 线程将
- * 无限等待; 修改"ThrdProc()"函数,去除不必要的信号检测函
- * 数, 提高用户回调函数的调用性能.
- ***********************************************************************/
- #include "swapi.h"
- #include "swstring.h"
- #include "swsignal.h"
- #include "swmem.h"
- #include "swthrd.h"
- // 线程的调度策略(1 - "SCHED_FIFO"实时调度策略,先到先服务; 2 - "SCHED_RR"实时调度策略,时间片轮转)
- #define MY_SCHEDPOLICY SCHED_RR
- typedef struct
- {
- // 线程的名称
- char name[32];
-
- // 线程的ID号
- pthread_t nThrdID;
- // 线程的控制事件
- void *hCtlEvent;
- // 线程的退出信号灯
- void *hEndSignal;
-
- // 线程的(用户)回调函数
- PThrdProc proc;
- unsigned long wParam;
- unsigned long lParam;
-
- // 线程是否暂停运行
- volatile bool bPause;
- // 线程是否正在执行(用户)回调函数还没有返回
- volatile bool bBusy;
- // 线程是否已退出
- volatile bool bQuit;
-
- } SThrdInfo;
- // 匿名线程计数器
- static int s_nameless_thrd_counter = 0;
- // 线程的执行函数
- static void ThrdProc(void *lpParameter);
- /* 创建线程, 成功后默认处于暂停状态 */
- void *sw_thrd_create(const char *name, int priority, int stack_size, PThrdProc proc,
- unsigned long wParam, unsigned long lParam)
- {
- SThrdInfo *pInfo = NULL;
- pthread_attr_t attr; // 线程的属性对象
- int policy = 0; // 调度策略
-
- pInfo = (SThrdInfo *)sw_heap_malloc(sizeof(SThrdInfo));
- if(!pInfo) goto ErrorP;
- memset(pInfo, 0, sizeof(SThrdInfo));
-
- // 设置线程的名称
- if(name) strncpy(pInfo->name, name, sizeof(pInfo->name)-1);
- else snprintf(pInfo->name, sizeof(pInfo->name)-1, "nameless%d thread", s_nameless_thrd_counter++);
-
- // 产生线程的控制事件
- pInfo->hCtlEvent = sw_signal_create();
- if(!pInfo->hCtlEvent) goto ErrorP;
-
- // 创建线程的退出信号灯
- pInfo->hEndSignal = sw_signal_create();
- if(!pInfo->hEndSignal) goto ErrorP;
-
- // 设置线程的(用户)回调函数
- pInfo->proc = proc;
- pInfo->wParam = wParam;
- pInfo->lParam = lParam;
-
- // 初始化线程属性对象
- pthread_attr_init(&attr);
-
- // 设置线程的调度策略
- if(priority > 0)
- {
- pthread_attr_getschedpolicy(&attr, &policy);
- if(policy != MY_SCHEDPOLICY)
- {
- policy = MY_SCHEDPOLICY;
- if(pthread_attr_setschedpolicy(&attr, policy) != 0) goto ErrorP;
- }
- }
- else pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); // 绑定的, 此线程将与系统中的所有线程进行竞争
-
- // 堆栈大小
- if(pthread_attr_setstacksize(&attr, stack_size) != 0) goto ErrorP;
-
- // 创建线程, 成功后线程默认处于暂停状态
- pInfo->bPause = true; pInfo->bBusy = false; pInfo->bQuit = false;
- if(pthread_create(&pInfo->nThrdID, &attr, (void *)ThrdProc, (void *)pInfo) != 0) goto ErrorP;
-
- // 销毁线程属性对象
- pthread_attr_destroy(&attr);
-
- // 设置线程的优先级
- sw_thrd_setPriority(pInfo, priority);
-
- // 等待线程状态稳定
- sw_thrd_delay(THRDWAIT_DELAY);
-
- return pInfo;
-
- ErrorP:
- pthread_attr_destroy(&attr); // 销毁线程属性对象
- sw_thrd_destroy(pInfo, 0);
-
- return NULL;
- }
- /* 销毁线程, 在"wait time <= timout(ms)"前尝试安全的关闭线程, "wait time > timout"后则强制关闭 */
- void sw_thrd_destroy(void *hThrd, int timeout)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo) return;
-
- if(pInfo->nThrdID != 0)
- {
- pInfo->bQuit = true;
- sw_thrd_resume(pInfo);
- if(sw_signal_wait(pInfo->hEndSignal, timeout) == 0) ; // 尝试安全的关闭线程
- else if(pthread_cancel(pInfo->nThrdID) != 0) // 强制关闭线程
- { sw_log_error("terminate %s error(errno=%d)!!", pInfo->name, errno); }
- pthread_join(pInfo->nThrdID, NULL);
- pInfo->nThrdID = 0;
- }
-
- if(pInfo->hCtlEvent) { sw_signal_destroy(pInfo->hCtlEvent); pInfo->hCtlEvent = NULL; }
-
- if(pInfo->hEndSignal) { sw_signal_destroy(pInfo->hEndSignal); pInfo->hEndSignal = NULL; }
-
- sw_heap_free(pInfo);
- }
- /* 暂停运行线程 */
- void sw_thrd_pause(void *hThrd)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo) return;
-
- while(sw_signal_wait(pInfo->hCtlEvent, 0) == 0) sw_thrd_delay(1);
- pInfo->bPause = true;
- }
- /* 继续运行线程 */
- void sw_thrd_resume(void *hThrd)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo) return;
-
- pInfo->bPause = false;
- sw_signal_give(pInfo->hCtlEvent);
- }
- /* 延时(毫秒) */
- void sw_thrd_delay(int ms)
- {
- if(ms < 0) select(0, NULL, NULL, NULL, NULL);
- else
- {
- struct timeval tv = { 0 };
- tv.tv_sec = ms/1000;
- tv.tv_usec = (ms%1000)*1000;
- select(0, NULL, NULL, NULL, &tv);
- }
- }
- /* 检查线程是否还存在 */
- bool sw_thrd_isAlive(void *hThrd)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo) return false;
-
- return (pInfo->nThrdID != 0 && pInfo->bQuit == false);
- }
- /* 检查线程是否正在运行: true = 是, false = 否 */
- bool sw_thrd_isRunning(void *hThrd)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo) return false;
-
- return (pInfo->nThrdID != 0 && pInfo->bQuit == false && pInfo->bPause == false);
- }
- /* 检查线程是否正在执行(用户)回调函数还没有返回: true = 是, false = 否 */
- bool sw_thrd_isBusy(void *hThrd)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo) return false;
-
- return pInfo->bBusy;
- }
- /* 设置线程名称 */
- bool sw_thrd_setName(void *hThrd, const char *name)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo || !name) return false;
-
- memset(pInfo->name, 0, sizeof(pInfo->name));
- strncpy(pInfo->name, name, sizeof(pInfo->name)-1);
-
- return true;
- }
- /* 取得线程名称 */
- char *sw_thrd_getName(void *hThrd, char *name)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo || !name) return NULL;
-
- strcpy(name, pInfo->name);
-
- return name;
- }
- /* 设置线程优先级 */
- bool sw_thrd_setPriority(void *hThrd, int priority)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
- struct sched_param sparam = { 0 };
-
- if(!pInfo) return false;
-
- sparam.__sched_priority = priority;
- if(pthread_setschedparam(pInfo->nThrdID, MY_SCHEDPOLICY, &sparam) == 0) return true;
- else return false;
- }
- /* 取得线程优先级 */
- int sw_thrd_getPriority(void *hThrd)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
- struct sched_param sparam = { 0 };
- int policy;
-
- if(!pInfo) return -1;
-
- if(pthread_getschedparam(pInfo->nThrdID, &policy, &sparam) == 0) return sparam.__sched_priority;
- else return -1;
- }
- /* 设置线程执行的(用户)回调函数 */
- bool sw_thrd_setProc(void *hThrd, PThrdProc proc, unsigned long wParam, unsigned long lParam)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo) return false;
-
- pInfo->proc = proc;
- pInfo->wParam = wParam;
- pInfo->lParam = lParam;
-
- return true;
- }
- /* 取得线程执行的(用户)回调函数 */
- void sw_thrd_getProc(void *hThrd, PThrdProc *proc, unsigned long *wParam, unsigned long *lParam)
- {
- SThrdInfo *pInfo = (SThrdInfo *)hThrd;
-
- if(!pInfo) return;
-
- if(proc) *proc = pInfo->proc;
- if(wParam) *wParam = pInfo->wParam;
- if(lParam) *lParam = pInfo->lParam;
- }
- // 线程的执行函数
- static void ThrdProc(void *lpParameter)
- {
- SThrdInfo *pInfo = (SThrdInfo *)lpParameter;
- int delay = 0;
-
- while(pInfo->bQuit == false)
- {
- if(pInfo->bPause) sw_signal_wait(pInfo->hCtlEvent, WAIT_FOREVER);
-
- if(pInfo->proc)
- {
- pInfo->bBusy = true;
- delay = pInfo->proc(pInfo->wParam, pInfo->lParam);
- pInfo->bBusy = false;
- }
- else delay = 1;
-
- if(delay < 0) pInfo->bQuit = true;
- else if(delay > 0) sw_signal_wait(pInfo->hCtlEvent, delay);
- }
-
- pInfo->proc = NULL;
- pInfo->wParam = pInfo->lParam = 0;
- sw_signal_give(pInfo->hEndSignal); // 点亮"退出信号灯", 表明线程已正常结束
-
- pthread_exit("thread normal exit.");
- }
|