執行緒一寫多讀的實驗
阿新 • • 發佈:2018-12-20
前言
demo中,一個執行緒在寫計數++, 另外一個執行緒在讀, 算出tps。遇到了tps算不準的問題。 後來發現是分母上的時間差用秒為單位的緣故(1.5秒和2.4秒用2個time(NULL)減之後都是2秒)。換成微秒時間再乘以1000000就正常了。 開始一度想使用__sync_xx系列函式讀取計數時,都同步一下。被同事指出這是在迴避問題,尷尬… 其實,有問題時,各種實驗都嘗試一下。通過實驗定位問題後,再解決就容易了。就像本次遇到的tps算不準的問題,如果嘗試了__sync_xx後,肯定還是tps不準。那我就嘗試下一個實驗方法,這被扣上回避問題的帽子,也是真尷尬。只能說,如果開始嘗試解決問題的方法對路,實驗少做一些而已。
寫了一個demo, 驗證"一寫多讀"。實驗證明,多個執行緒讀值時,讀到的都是寫執行緒寫的值,不會讀到亂的值。
做這個實驗,對linux執行緒的用法(傳執行緒上下文, 執行緒啟動,使用執行緒上下文,執行緒停止)複習了一次。使用linux執行緒時,設定執行緒上下文退出標記,讓執行緒檢測到退出標記後,自己退出。
demo下載點
稍後上傳
執行效果
Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.124 : remove_file()] : failed : remove [/var/log/test_time__file_flag_to_shutdown], error[-1] = [No such file or directory] Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.124 : remove_file()] : failed : remove [/var/log/test_time__file_flag_to_thread_run_all], error[-1] = [No such file or directory] Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.124 : remove_file()] : failed : remove [/var/log/test_time__file_flag_to_debug], error[-1] = [No such file or directory] Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.102 : main()] : MAKE_FILE_MACRO__BIN_NAME = [test_time] Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.460 : fn_test()] : >> fn_test() Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.462 : fn_test()] : l_cpu_numbers = 16 Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.465 : fn_test()] : l_thread_numbers = 32 Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[0] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[1] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[2] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[3] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.348 : thread_proc_write()] : >> thread_proc_write[0] Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[1], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[2], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[4] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[5] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[3], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[6] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[7] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[5], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[8] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[6], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[9] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[7], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[10] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[4], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[11], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[8], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[10], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[11] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[9], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[12] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[12], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[13] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[13], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[14] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[14], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[15] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[15], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[16] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[16], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[17] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[17], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[18], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[18] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[19] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[19], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[20] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[20], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[21] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[21], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[22], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[22] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[23] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[23], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[24], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[24] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[25] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[25], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[26] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[26], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[27] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[27], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[28] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[28], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[29] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[29], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[30] create Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.396 : thread_proc_read()] : >> thread_proc_read[30], wait FILE_FLAG_THREAD_RUN_ALL Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.280 : thread_proc_env_check()] : >> thread_proc_env_check[31] Oct 16 06:02:59 debian8 test_time: [MY_LOGD : main.cpp.507 : fn_test()] : ok : pthread[31] create ... Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[5] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.353 : thread_proc_write()] : >> thread_proc_write[0] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[10] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[8] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[13] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[2] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[1] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[6] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[9] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[16] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[4] find FILE_FLAG_THREAD_RUN_ALL, will be run Oct 16 06:03:58 debian8 test_time: [MY_LOGD : main.cpp.401 : thread_proc_read()] : >> thread_proc_read[20] find FILE_FLAG_THREAD_RUN_ALL, will be run ... Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[6] tps = 2013, ull_cnt_prev = 217230, ull_time_prev = 1539641149002014 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[19] tps = 2013, ull_cnt_prev = 217231, ull_time_prev = 1539641149002510 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[4] tps = 2014, ull_cnt_prev = 217232, ull_time_prev = 1539641149003070 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[1] tps = 2012, ull_cnt_prev = 217233, ull_time_prev = 1539641149003532 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[24] tps = 2012, ull_cnt_prev = 217233, ull_time_prev = 1539641149003512 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[9] tps = 2013, ull_cnt_prev = 217234, ull_time_prev = 1539641149003998 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[17] tps = 2012, ull_cnt_prev = 217236, ull_time_prev = 1539641149004498 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[26] tps = 2013, ull_cnt_prev = 217238, ull_time_prev = 1539641149006115 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[27] tps = 2014, ull_cnt_prev = 217238, ull_time_prev = 1539641149006145 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[14] tps = 2013, ull_cnt_prev = 217239, ull_time_prev = 1539641149006304 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[10] tps = 2013, ull_cnt_prev = 217239, ull_time_prev = 1539641149006256 Oct 16 06:05:50 debian8 test_time: [MY_LOGD : main.cpp.243 : calc_tps_and_show()] : thread[25] tps = 2013, ull_cnt_prev = 217240, ull_time_prev = 1539641149006591 ... Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.286 : thread_proc_env_check()] : thread_proc_env_check[31] recv quit command, stop other thread ... Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[0].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[1].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[2].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[3].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[4].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[5].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[6].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[7].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[8].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[9].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[10].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[11].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[12].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[13].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[14].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.362 : thread_proc_write()] : >> thread_proc_write[0] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.375 : thread_proc_write()] : << thread_proc_write[0] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[15].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[16].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[17].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[18].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[19].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[20].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[21].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[22].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[23].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[24].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[25].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[26].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[27].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[28].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[29].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.300 : thread_proc_env_check()] : set _p_ctx->p_thread_ctx_parent[30].b_request_quit_thread = true Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.313 : thread_proc_env_check()] : >> wait _p_ctx->p_thread_ctx_parent[1].h_thread end Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[11] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[4] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[11] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[4] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[22] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[22] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[12] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[12] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[19] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[19] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[18] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[18] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[9] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[9] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[13] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[13] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[25] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[25] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[21] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[21] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[26] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[26] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[15] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[15] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[10] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[10] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[20] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[20] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[6] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[6] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[16] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[16] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[1] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[1] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[24] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[24] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[23] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[23] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[5] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[5] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[30] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[30] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[29] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[29] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[17] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[17] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[27] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[27] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[2] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[2] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[28] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[28] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[3] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[3] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.315 : thread_proc_env_check()] : << wait _p_ctx->p_thread_ctx_parent[1].h_thread end Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.313 : thread_proc_env_check()] : >> wait _p_ctx->p_thread_ctx_parent[7].h_thread end Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[8] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[8] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[7] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[7] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.418 : thread_proc_read()] : >> thread_proc_read[14] find b_request_quit_thread, will be quit Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.431 : thread_proc_read()] : << thread_proc_read[14] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.315 : thread_proc_env_check()] : << wait _p_ctx->p_thread_ctx_parent[7].h_thread end Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.327 : thread_proc_env_check()] : << thread_proc_env_check[31] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.529 : fn_test()] : ok : stop thread_env_check Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.127 : remove_file()] : ok : remove [/var/log/test_time__file_flag_to_shutdown] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.127 : remove_file()] : ok : remove [/var/log/test_time__file_flag_to_thread_run_all] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.124 : remove_file()] : failed : remove [/var/log/test_time__file_flag_to_debug], error[-1] = [No such file or directory] Oct 16 06:06:40 debian8 test_time: [MY_LOGD : main.cpp.110 : main()] : THE END
實驗
// @file main.cpp // @brief 測試時間取值(us)和計數(一寫多讀) // @note // 實驗環境: // debian8.8 // // 除錯: // when debug, see log => tail -f /var/log/messages | grep MY_LOGD #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <unistd.h> #include <limits.h> #include <signal.h> #include <errno.h> #include <sys/time.h> #include <pthread.h> #include <string> #include "const_define.h" // 執行緒自己的私有資料 typedef struct _tag_thread_private_data { long l_tps; // 算出的當前tps值 ull ull_time_prev; // 上一次記錄tps的時間 ull ull_cnt_prev; // 上一次記錄的計數器值 _tag_thread_private_data() { l_tps = 0; ull_time_prev = 0; ull_cnt_prev = 0; } }TAG_THREAD_PRIVATE_DATA; // 執行緒之間共享的資料 typedef struct _tag_thread_share_data { ull ull_cnt; // 一寫多讀的計數器 _tag_thread_share_data() { ull_cnt = 0; } }TAG_THREAD_SHARE_DATA; // 執行緒上下文 typedef struct _tag_thread_context { bool b_init_h_thread; // h_thread is init ? pthread_t h_thread; // 執行緒控制代碼 int i_thread_sn; // 執行緒號碼 _tag_thread_context* p_thread_ctx_parent; // 總的執行緒上下文, 用於環境檢測執行緒停止其他執行緒 long l_thread_numbers; // p_thread_ctx_parent 對應的執行緒數量(p_thread_ctx_parent[]的組數size) TAG_THREAD_SHARE_DATA* p_share_data; // 執行緒之間共享的資料結構 TAG_THREAD_PRIVATE_DATA thread_private_data; // 執行緒的私有資料 bool b_request_quit_thread; // 請求退出執行緒 _tag_thread_context() { // h_thread = NULL; // pthread_t isn't pointer type, can't set to NULL b_init_h_thread = false; i_thread_sn = -1; p_thread_ctx_parent = NULL; l_thread_numbers = 0; p_share_data = NULL; b_request_quit_thread = false; } } TAG_THREAD_CONTEXT; void init(const char* psz_log_owner_name); void uninit(); void proc_sig_term(int num); int fn_test(int argc, char** argv); bool is_file_exist(const char* psz_file_path_name, int& i_err_code, std::string& str_err_msg); void read_and_show_context(TAG_THREAD_CONTEXT* p_ctx); void write_and_show_context(TAG_THREAD_CONTEXT* p_ctx); void show_ull_by_time(const char* psz_tip, ull ull_val); void calc_tps_and_show(TAG_THREAD_CONTEXT* p_ctx); void remove_flag_file(); void remove_file(const char* psz_file_path_name); typedef void* (*PFN_thread_proc_env_check)(void* p_ctx); void* thread_proc_env_check(void* p_ctx); void* thread_proc_write(void* p_ctx); void* thread_proc_read(void* p_ctx); int main(int argc, char** argv) { char sz_buf[MAX_MSG_LENGTH] = {'\0'}; #ifdef MAKE_FILE_MACRO__BIN_NAME sprintf(sz_buf, "%s", MAKE_FILE_MACRO__BIN_NAME); init(sz_buf); MYLOG_D("MAKE_FILE_MACRO__BIN_NAME = [%s]\n", MAKE_FILE_MACRO__BIN_NAME); #else init(NULL); #endif // #ifdef MAKE_FILE_MACRO__BIN_NAME fn_test(argc, argv); uninit(); MYLOG_D("THE END\n"); return EXIT_SUCCESS; } void remove_file(const char* psz_file_path_name) { int i_rc = 0; if (NULL != psz_file_path_name) { i_rc = remove(psz_file_path_name); if (EOK != i_rc) { MYLOG_D("failed : remove [%s], error[%d] = [%s]\n", psz_file_path_name, i_rc, strerror(errno)); } else { MYLOG_D("ok : remove [%s]\n", psz_file_path_name); } } } void remove_flag_file() { remove_file(FILE_FLAG_SHUTDOWN); remove_file(FILE_FLAG_THREAD_RUN_ALL); remove_file(FILE_FLAG_DEBUG); } void uninit() { remove_flag_file(); } void proc_sig_term(int num) { MYLOG_D("SIGTERM = %d, num = %d\n", SIGTERM, num); MYLOG_D("maybe can do some clean task before quit\n"); exit(1); } void init(const char* psz_log_owner_name) { int i = 0; MYLOG_D("%s\n", TITLE_LINE80); MYLOG_D("%s %s %s\n", (NULL != psz_log_owner_name) ? psz_log_owner_name : "test_prog", PROG_VER, RELEASE_TIME); MYLOG_D("%s\n", TITLE_LINE80); // daemon(0, 0); // clear screen (print 25 empty line) for (i = 0; i < 25; i++) { MYLOG_D("\n"); } signal(SIGTERM, proc_sig_term); remove_flag_file(); } bool is_file_exist(const char* psz_file_path_name, int& i_err_code, std::string& str_err_msg) { bool b_rc = false; int i_rc = -1; do { if ((NULL == psz_file_path_name) || (0 == strlen(psz_file_path_name))) { i_err_code = -1; str_err_msg = "param 1 error"; break; } i_rc = access(psz_file_path_name, F_OK); if (0 != i_rc) { i_err_code = errno; str_err_msg = strerror(i_err_code); } else { b_rc = true; } } while (0); return b_rc; } void show_ull_by_time(const char* psz_tip, ull ull_val) { struct timeval tv_now; ull ull_time_now = 0; gettimeofday(&tv_now, NULL); ull_time_now = tv_now.tv_sec; ull_time_now *= 1000000; ull_time_now += tv_now.tv_usec; MYLOG_D("%s : ull_val = %llu, time now = %llu, %ld.%ld\n", (NULL != psz_tip) ? psz_tip : "NULL", ull_val, ull_time_now, tv_now.tv_sec, tv_now.tv_usec); } void calc_tps_and_show(TAG_THREAD_CONTEXT* p_ctx) { struct timeval tv_now; ull ull_time_now = 0; ull ull_cnt_val_by_writer = 0; if (NULL != p_ctx) { gettimeofday(&tv_now, NULL); ull_time_now = tv_now.tv_sec; ull_time_now *= 1000000; ull_time_now += tv_now.tv_usec; ull_cnt_val_by_writer = p_ctx->p_thread_ctx_parent->p_share_data->ull_cnt; if ((p_ctx->thread_private_data.ull_cnt_prev > 0) && (p_ctx->thread_private_data.ull_time_prev > 0)) { p_ctx->thread_private_data.l_tps = 1.0f * (ull_cnt_val_by_writer - p_ctx->thread_private_data.ull_cnt_prev) / (ull_time_now - p_ctx->thread_private_data.ull_time_prev) * 1000000; MYLOG_D("thread[%d] tps = %ld, ull_cnt_prev = %llu, ull_time_prev = %llu", p_ctx->i_thread_sn, p_ctx->thread_private_data.l_tps, p_ctx->thread_private_data.ull_cnt_prev, p_ctx->thread_private_data.ull_time_prev); } p_ctx->thread_private_data.ull_cnt_prev = ull_cnt_val_by_writer; p_ctx->thread_private_data.ull_time_prev = ull_time_now; } } void read_and_show_context(TAG_THREAD_CONTEXT* p_ctx) { TAG_THREAD_CONTEXT* _p_ctx = (TAG_THREAD_CONTEXT*)p_ctx; if ((NULL != _p_ctx) && (NULL != _p_ctx->p_share_data)) { show_ull_by_time("rd", _p_ctx->p_share_data->ull_cnt); } } void write_and_show_context(TAG_THREAD_CONTEXT* p_ctx) { TAG_THREAD_CONTEXT* _p_ctx = (TAG_THREAD_CONTEXT*)p_ctx; if ((NULL != _p_ctx) && (NULL != _p_ctx->p_share_data)) { _p_ctx->p_share_data->ull_cnt++; show_ull_by_time("wr", _p_ctx->p_share_data->ull_cnt); } } void* thread_proc_env_check(void* p_ctx) { TAG_THREAD_CONTEXT* _p_ctx = (TAG_THREAD_CONTEXT*)p_ctx; int i = 0; do { if (NULL == _p_ctx) { break; } MYLOG_D(">> thread_proc_env_check[%d]\n", _p_ctx->i_thread_sn); do { if (_p_ctx->b_request_quit_thread) { // 等主執行緒來停止環境檢測執行緒, 環境檢測執行緒再去停止其他工作執行緒 MYLOG_D("thread_proc_env_check[%d] recv quit command, stop other thread ...\n", _p_ctx->i_thread_sn); // close read thread // set quit command to all other thread for (i = 0; i < _p_ctx->l_thread_numbers; i++) { if (_p_ctx->p_thread_ctx_parent[i].i_thread_sn == _p_ctx->i_thread_sn) { // 這些執行緒也包含本執行緒, 只處理其他執行緒 continue; } if (pthread_kill(_p_ctx->p_thread_ctx_parent[i].h_thread, 0) == 0) { // if thread is still active, first set thread quit falg // thread will quit by p_thread_ctx[i].b_request_quit_thread _p_ctx->p_thread_ctx_parent[i].b_request_quit_thread = true; MYLOG_D("set _p_ctx->p_thread_ctx_parent[%d].b_request_quit_thread = true\n", i); } } // wait all other thread over quit by them slef for (i = 0; i < _p_ctx->l_thread_numbers; i++) { if (_p_ctx->p_thread_ctx_parent[i].i_thread_sn == _p_ctx->i_thread_sn) { // 這些執行緒也包含本執行緒, 只處理其他執行緒 continue; } if (pthread_kill(_p_ctx->p_thread_ctx_parent[i].h_thread, 0) == 0) { // then wait it exit MYLOG_D(">> wait _p_ctx->p_thread_ctx_parent[%d].h_thread end\n", i); pthread_join(_p_ctx->p_thread_ctx_parent[i].h_thread, NULL); MYLOG_D("<< wait _p_ctx->p_thread_ctx_parent[%d].h_thread end\n", i); } } break; } usleep(US_SLEEP_VAL_FO_READER); } while (1); } while (0); if (NULL != _p_ctx) { MYLOG_D("<< thread_proc_env_check[%d]\n", _p_ctx->i_thread_sn); pthread_exit((void*)(intptr_t)_p_ctx->i_thread_sn); } else { MYLOG_D("<< thread_proc_env_check\n"); pthread_exit(NULL); } return NULL; } void* thread_proc_write(void* p_ctx) { TAG_THREAD_CONTEXT* _p_ctx = (TAG_THREAD_CONTEXT*)p_ctx; int i_err_code = 0; std::string str_err = ""; do { if (NULL == _p_ctx) { break; } MYLOG_D(">> thread_proc_write[%d]\n", _p_ctx->i_thread_sn); // wait thread run flag do { if (is_file_exist(FILE_FLAG_THREAD_RUN_ALL, i_err_code, str_err)) { MYLOG_D(">> thread_proc_write[%d] find FILE_FLAG_THREAD_RUN_ALL, will be run\n", _p_ctx->i_thread_sn); break; } usleep(US_SLEEP_VAL_FO_READER); } while (1); do { if (_p_ctx->b_request_quit_thread) { MYLOG_D(">> thread_proc_write[%d] find b_request_quit_thread, will be quit\n", _p_ctx->i_thread_sn); break; } // write_and_show_context(_p_ctx); _p_ctx->p_thread_ctx_parent->p_share_data->ull_cnt++; usleep(US_SLEEP_VAL_FO_WRITER); // 計數增加的頻率遠高於計數讀的頻率 } while (1); } while (0); if (NULL != _p_ctx) { MYLOG_D("<< thread_proc_write[%d]\n", _p_ctx->i_thread_sn); pthread_exit((void*)(intptr_t)_p_ctx->i_thread_sn); } else { MYLOG_D("<< thread_proc_write\n"); pthread_exit(NULL); } return NULL; } void* thread_proc_read(void* p_ctx) { TAG_THREAD_CONTEXT* _p_ctx = (TAG_THREAD_CONTEXT*)p_ctx; int i_err_code = 0; std::string str_err = ""; do { if (NULL == _p_ctx) { break; } MYLOG_D(">> thread_proc_read[%d], wait FILE_FLAG_THREAD_RUN_ALL\n", _p_ctx->i_thread_sn); // wait thread run flag do { if (is_file_exist(FILE_FLAG_THREAD_RUN_ALL, i_err_code, str_err)) { MYLOG_D(">> thread_proc_read[%d] find FILE_FLAG_THREAD_RUN_ALL, will be run\n", _p_ctx->i_thread_sn); break; } usleep(US_SLEEP_VAL_FO_READER); } while (1); do { if (1 == _p_ctx->i_thread_sn) { if (is_file_exist(FILE_FLAG_DEBUG, i_err_code, str_err)) { if (1 == _p_ctx->i_thread_sn) { MYLOG_D(""); // for debug #1 thread } } } if (_p_ctx->b_request_quit_thread) { MYLOG_D(">> thread_proc_read[%d] find b_request_quit_thread, will be quit\n", _p_ctx->i_thread_sn); break; } // read_and_show_context(_p_ctx); calc_tps_and_show(_p_ctx); usleep(US_SLEEP_VAL_FO_READER); } while (1); } while (0); if (NULL != _p_ctx) { MYLOG_D("<< thread_proc_read[%d]\n", _p_ctx->i_thread_sn); pthread_exit((void*)(intptr_t)_p_ctx->i_thread_sn); } else { MYLOG_D("<< thread_proc_read\n"); pthread_exit(NULL); } return NULL; } // @ref https://computing.llnl.gov/tutorials/pthreads/ // POSIX Threads Programming int fn_test(int argc, char** argv) { bool b_rc = false; int i_err_code = 0; long l_cpu_numbers = 0; long l_thread_numbers = 0; std::string str_err = ""; TAG_THREAD_CONTEXT* p_thread_ctx = NULL; TAG_THREAD_SHARE_DATA share_data; pthread_attr_t thread_attr; int i = 0; int i_thread_sn_env_check = 0; // 環境檢測執行緒的號碼 PFN_thread_proc_env_check pfn_thread_proc_now = NULL; MYLOG_D(">> fn_test()\n"); l_cpu_numbers = sysconf(_SC_NPROCESSORS_ONLN); MYLOG_D("l_cpu_numbers = %ld\n", l_cpu_numbers); l_thread_numbers = l_cpu_numbers * 2; MYLOG_D("l_thread_numbers = %ld\n", l_thread_numbers); pthread_attr_init(&thread_attr); pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); // create thread, p_thread_ctx = new TAG_THREAD_CONTEXT[l_thread_numbers]; for (i = 0; i < l_thread_numbers; i++) { p_thread_ctx[i].p_thread_ctx_parent = p_thread_ctx; p_thread_ctx[i].l_thread_numbers = l_thread_numbers; p_thread_ctx[i].p_share_data = &share_data; p_thread_ctx[i].i_thread_sn = i; if (i == (l_thread_numbers - 1)) { // 最後一個執行緒 // 最後一個執行緒是檢測執行緒(檢測是否要退出, 如果檢測操作放在主執行緒中, 優先順序低, 沒機會執行到檢測程式碼) // 因為要操作其他執行緒控制代碼(e.g. 發現shutdown檔案標誌後), 如果shutdown檔案已經存在, // 這種場景下, 如果其他執行緒還沒建立,去操作其他無效的執行緒控制代碼,會崩潰(segment fault) pfn_thread_proc_now = thread_proc_env_check; i_thread_sn_env_check = i; // 儲存管理執行緒的號碼 } else { switch (i) { // case 不能為變數... case 0: { // 1#執行緒是寫執行緒, pfn_thread_proc_now = thread_proc_write; } break; default: { // 其他執行緒是讀執行緒 pfn_thread_proc_now = thread_proc_read; } break; } } if (EOK == pthread_create( &p_thread_ctx[i].h_thread, &thread_attr, pfn_thread_proc_now, p_thread_ctx + i)) { p_thread_ctx[i].b_init_h_thread = true; MYLOG_D("ok : pthread[%d] create\n", p_thread_ctx[i].i_thread_sn); } else { MYLOG_D("error : pthread[%d] create : %s\n", p_thread_ctx[i].i_thread_sn, strerror(errno)); break; } } do { if (is_file_exist(FILE_FLAG_SHUTDOWN, i_err_code, str_err)) { MYLOG_D("find shutdown file\n"); pthread_attr_destroy(&thread_attr); // 停掉環境檢測執行緒(環境檢測執行緒負責停掉其他執行緒) if (pthread_kill(p_thread_ctx[i_thread_sn_env_check].h_thread, 0) == 0) { // if thread is still active, first set thread quit falg // thread will quit by p_thread_ctx[i_thread_sn_env_check].b_request_quit_thread p_thread_ctx[i_thread_sn_env_check].b_request_quit_thread = true; MYLOG_D("stop thread_env_check ...\n"); pthread_join(p_thread_ctx[i_thread_sn_env_check].h_thread, NULL); } MYLOG_D("ok : stop thread_env_check\n"); break; } // if not recv user quit command(/var/log/shutdown_test_time), run continue; usleep(US_SLEEP_VAL_FO_READER); } while (1); SAFE_DELETE_ARY(p_thread_ctx); return b_rc; }
// @file const_define.h
#if not defined(__CONST_DEFINE_H__)
#define __CONST_DEFINE_H__
#include <string.h>
#include <string>
#include <list>
#include <syslog.h>
#define PROG_VER "1.0.0.1"
#define RELEASE_TIME "2018-11-11 14:04"
typedef unsigned long long ull;
#ifndef EOK
#define EOK 0
#endif // #ifndef EOK
#define MAX_MSG_LENGTH (1024 * 4)
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) \
if (NULL != (p)) { \
delete (p); \
(p) = NULL; \
}
#endif // #ifndef SAFE_DELETE
#ifndef SAFE_DELETE_ARY
#define SAFE_DELETE_ARY(p) \
if (NULL != (p)) { \
delete[] (p); \
(p) = NULL; \
}
#endif // #ifndef SAFE_DELETE
#define TITLE_LINE80 "================================================================================"
#define LINE80 "--------------------------------------------------------------------------------"
#if not defined(MYLOG_D)
#define MYLOG_D(fmt, ...) \
do { \
syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "MY_LOGD", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
} while (0);
#endif // #if not defined(MYLOG_D)
#define FILE_FLAG_SHUTDOWN "/var/log/test_time__file_flag_to_shutdown"
#define FILE_FLAG_THREAD_RUN_ALL "/var/log/test_time__file_flag_to_thread_run_all"
#define FILE_FLAG_DEBUG "/var/log/test_time__file_flag_to_debug"
#define US_SLEEP_VAL_FO_WRITER 10 // 10微妙
#define US_SLEEP_VAL_FO_READER 1000000 // 1秒
#endif // #if not defined(__CONST_DEFINE_H__)
# ==============================================================================
# @file makefile
# ==============================================================================
# @note
# howto build project
# make BIN_NAME="bin_name_by_you_want" rebuild
# makefile code need tab key not sapce key
MY_MAKE_FILE_PATH_NAME = $(MAKEFILE_LIST)
# macro from Makefile command line
# BIN_NAME
# macro to C project
MAKE_FILE_MACRO__BIN_NAME="make_file_macro__bin_name"
# var define on Makefile
BIN = output_not_give_bin_name
IS_BUILD_TYPE_VALID = 0
ifdef BIN_NAME
IS_BUILD_TYPE_VALID = 1
BIN = $(BIN_NAME)
MAKE_FILE_MACRO__BIN_NAME=$(BIN_NAME)
else
IS_BUILD_TYPE_VALID = 0
endif
LINE80 = --------------------------------------------------------------------------------
# CC = g++ -std=c++98
CC = g++
# -Werror is "warning as error"
CFLAGS = -Wall -Werror -g
INC = -I.
LIBPATH = -L/usr/lib/ -L/usr/local/lib/
ifeq (1, $(IS_BUILD_TYPE_VALID))
LIBS = -lstdc++ -pthread
else
LIBS =
endif
DEPEND_CODE_DIR = ../common/ \
DEPEND_CODE_SRC = $(shell find $(DEPEND_CODE_DIR) -name '*.cpp')
DEPEND_CODE_OBJ = $(DEPEND_CODE_SRC:.cpp=.o)
ROOT_CODE_SRC = $(shell find ./ -name '*.cpp')
ROOT_CODE_OBJ = $(ROOT_CODE_SRC:.cpp=.o)
SUB_CODE_DIR = ./empty_dir
SUB_CODE_SRC = $(shell find $(SUB_CODE_DIR) -name '*.cpp')
SUB_CODE_OBJ = $(SUB_CODE_SRC:.cpp=.o)
.PHONY: help
help:
clear
@echo "usage:"
@echo
@echo "build project by given bin name"
@echo "make BIN_NAME=\"bin_name_by_you_want\" rebuild"
@echo
.PHONY: clean
clean:
clear
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo "make clean begin"
@echo $(LINE80)
@echo "@file $(MY_MAKE_FILE_PATH_NAME)"
@echo "IS_BUILD_TYPE_VALID = $(IS_BUILD_TYPE_VALID)"
@echo "BIN = $(BIN)"
@echo $(LINE80)
rm -f $(ROOT_CODE_OBJ) $(DEPEND_CODE_OBJ) $(SUB_CODE_OBJ)
ifeq (1, $(IS_BUILD_TYPE_VALID))
rm -f ./$(BIN)
endif
@echo "make clean over"
.PHONY: all
all:$(BIN)
@echo $(LINE80)
@echo make all
chmod 777 ./$(BIN)
find . -name "$(BIN)"
$(BIN) : $(ROOT_CODE_OBJ) $(DEPEND_CODE_OBJ) $(SUB_CODE_OBJ)
$(CC) $(CFLAGS) -o [email protected] $^ $(SHLIBS) $(INC) $(LIBPATH) $(LIBS)
.cpp.o:
$(CC) -c $(CFLAGS) -DMAKE_FILE_MACRO__BIN_NAME="\"$(MAKE_FILE_MACRO__BIN_NAME)\"" $^ -o [email protected] $(INC) $(LIBPATH) $(LIBS)
.PHONY: rebuild
rebuild:
make -f $(MY_MAKE_FILE_PATH_NAME) clean
ifeq (1, $(IS_BUILD_TYPE_VALID))
@echo $(LINE80)
make -f $(MY_MAKE_FILE_PATH_NAME) all
chmod 775 ./$(BIN)
ldd ./$(BIN)
else
@echo $(LINE80)
@echo "error : Makefile command line input error, please see help"
@echo "please run => make help"
@echo $(LINE80)
endif
#!/bin/bash
# ==============================================================================
# @file build_all_project.sh
# ==============================================================================
make BIN_NAME="test_time" rebuild