{"id":726,"date":"2022-11-23T22:59:40","date_gmt":"2022-11-23T14:59:40","guid":{"rendered":"https:\/\/niuguodong.com\/?p=726"},"modified":"2025-12-24T13:09:09","modified_gmt":"2025-12-24T05:09:09","slug":"c%e8%af%ad%e8%a8%80%e5%a4%9a%e7%ba%bf%e7%a8%8b%e6%b5%8b%e8%af%95","status":"publish","type":"post","link":"https:\/\/niuguodong.com\/index.php\/2022\/11\/23\/c%e8%af%ad%e8%a8%80%e5%a4%9a%e7%ba%bf%e7%a8%8b%e6%b5%8b%e8%af%95\/","title":{"rendered":"C\u8bed\u8a00\u591a\u7ebf\u7a0b\u6d4b\u8bd5"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">\u6d4b\u8bd5\u4ee3\u7801<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n#include &lt;threads.h>\n#include &lt;time.h>\n#include &lt;string.h>\n#include &lt;stdlib.h>\n#include &lt;stdbool.h>\n#include \"unistd.h\"\n\n\nthrd_t thread_1 = 0;\nthrd_t thread_2 = 0;\nthrd_t thread_3 = 0;\nthrd_t thread_4 = 0;\nthrd_t thread_5 = 0;\nthrd_t thread_6 = 0;\nthrd_t thread_7 = 0;\nthrd_t thread_8 = 0;\n\nint thread1(void* param)\n{\n    puts(\"thread1 start\");\n\n    int run_time = 0;\n    while(1)\n    {\n        run_time++;\n        sleep(1);\n        printf(\"thread1:run_time=%d\\n\",run_time);\n        if(run_time==5)\n        {\n            thrd_exit(123);\n            puts(\"thread1 exit.\");  \/\/\u4e0d\u4f1a\u6267\u884c\n        }\n    }\n}\n\n\nint thread2(void* param)\n{\n    puts(\"thread2 start\");\n    int thread1_result = 0;\n\n    int run_time = 0;\n    while(1)\n    {\n        run_time++;\n        sleep(1);\n        printf(\"thread2:run_time=%d\\n\",run_time);\n        if(run_time==3)\n        {\n            puts(\"thread2:thrd_join(thread_1, &amp;thread1_result)\");\n            int err = thrd_join(thread_1, &amp;thread1_result);\n            printf(\"err=%d\\n\", err);\n            printf(\"thread1_result=%d\\n\", thread1_result);\n        }\n        if(run_time==6)\n        {\n            puts(\"thread2 exit.\");\n            thrd_exit(0);\n            puts(\"thread2 exited.\");    \/\/\u4e0d\u4f1a\u6267\u884c\n        }\n    }\n}\n\n\nint thread3(void* param)\n{\n    puts(\"thread3 start\");\n    int thread1_result = 0;\n\n    int run_time = 0;\n    while(1)\n    {\n        run_time++;\n        sleep(1);\n        printf(\"thread3:run_time=%d\\n\",run_time);\n        if(run_time==5)\n        {\n            thrd_t curthr_id = thrd_current();\n            if(thrd_equal(curthr_id, thread_3))\n            {\n                printf(\"thread3: curthr_id equal thread_3\\n\");\n            }\n            printf(\"thread3:curthr_id=%ld\\n\", curthr_id);\n        }\n        if(run_time==6)\n        {\n            puts(\"thread3 exit.\");\n            thrd_exit(0);\n        }\n    }\n}\n\n\nint thread4(void* param)\n{\n    puts(\"thread4 start\");\n    int thread1_result = 0;\n\n    int run_time = 0;\n    while(1)\n    {\n        run_time++;\n        sleep(1);\n        printf(\"thread4:run_time=%d\\n\",run_time);\n        if(run_time==3)\n        {\n            puts(\"thread4:thrd_detach(thread_3)\");\n            int err = thrd_detach(thread_3);    \/\/\u5206\u79bb\u7ebf\u7a0b3, \u4f7f\u5176\u8d44\u6e90\u5728\u7ebf\u7a0b\u7ed3\u675f\u540e\u81ea\u52a8\u91ca\u653e\n            printf(\"err=%d\\n\", err);\n        }\n        if(run_time==8)\n        {\n            puts(\"thread4 exit.\");\n            thrd_exit(0);\n        }\n    }\n}\n\n\nint thread6(void* param)\n{\n    puts(\"thread6 start\");\n\n    int run_time = 0;\n    while(1)\n    {\n        run_time++;\n        sleep(1);\n        printf(\"thread6:run_time=%d\\n\",run_time);\n        if(run_time==5)\n        {\n            puts(\"thread6 exit.\");\n            thrd_exit(0);\n        }\n    }\n}\n\n\nint thread5(void* param)\n{\n    puts(\"thread5 ok\");\n    int thread1_result = 0;\n\n    int run_time = 0;\n    while(1)\n    {\n        run_time++;\n        sleep(1);\n        printf(\"thread5:run_time=%d\\n\",run_time);\n        if(run_time==3)\n        {\n            thrd_t curthr_id = thrd_current();\n            printf(\"thread5:curthr_id=%ld\\n\", curthr_id);\n            printf(\"Time: %s\", ctime(&amp;(time_t){time(NULL)}));\n            thrd_sleep(&amp;(struct timespec){.tv_sec=5}, NULL);\n            printf(\"Time: %s\", ctime(&amp;(time_t){time(NULL)}));\n        }\n        if(run_time==6)\n        {\n            int err = thrd_create(&amp;thread_6, thread6, NULL);\n            if(err!=thrd_success)   \n            {\n                printf(\"\\033&#91;31merror:%s,in line %d:create thread6 failed:err=%d\\033&#91;0m\\n\", \\\n                    __FILE__, __LINE__, err);\n            }\n        }\n        if(run_time==8)\n        {\n            puts(\"thread5 exit.\");\n            thrd_exit(0);\n        }\n    }\n}\n\n\ntypedef struct\n{\n    char name&#91;32];\n    int run_time_max;\n    int sleep_time;\n}thread7_param_t;\n\nmtx_t mutex_sum;\nbool mutex_sum_ok = false;\n\nstatic int test_sum(const char* t_name, int runtime, int a, int b)\n{\n    static int c = 0;\n    if(mutex_sum_ok)\n    {\n        mtx_lock(&amp;mutex_sum);\n    }\n    c++;\n    int d = a + b + c;\n    printf(\"%s, test_sum(start%d): a=%d, b=%d, c=%d\\n\", t_name, runtime, a, b, c);\n    if(a>=100)\n    {\n        thrd_sleep(&amp;(struct timespec){.tv_nsec=500000000}, NULL);\n    }\n\n    printf(\"%s, test_sum(end%d): a=%d, b=%d, c=%d\\n\", t_name, runtime, a, b, c);\n\n    int ret = a+b+c;\n    if(mutex_sum_ok)\n    {\n        mtx_unlock(&amp;mutex_sum);\n    }\n    \n    if(ret!=d)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d: %s, test_sum(%d) result error:ret=%d, d=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, t_name, runtime, ret, d);\n    }\n    return ret;\n}\n\nint thread7(void* param)\n{\n    thread7_param_t* p_param = (thread7_param_t*)param;\n    printf(\"%s start\\n\", p_param->name);\n    printf(\"%s: sleep_time=%d ns\\n\", p_param->name, p_param->sleep_time);\n\n    int run_time = 0;\n    while(1)\n    {\n        run_time++;\n        thrd_sleep(&amp;(struct timespec){.tv_nsec=p_param->sleep_time}, NULL);\n        printf(\"%s:run_time=%d\\n\", p_param->name, run_time);\n\n        int sum = test_sum(p_param->name, run_time, run_time*30, 1);\n        printf(\"%s: sum=%d\\n\", p_param->name, sum);\n\n        if(run_time==p_param->run_time_max)\n        {\n            printf(\"%s exit.\\n\", p_param->name);\n            thrd_exit(0);\n        }\n    }\n}\n\nvoid printf_all_thread_id(void)\n{\n    printf(\"All thread id:\\n\");\n    printf(\"thread_1=%ld, thread_2=%ld\\n\", thread_1, thread_2);\n    printf(\"thread_3=%ld, thread_4=%ld\\n\", thread_3, thread_4);\n    printf(\"thread_5=%ld, thread_6=%ld\\n\", thread_5, thread_6);\n    printf(\"thread_7=%ld, thread_8=%ld\\n\", thread_7, thread_8);\n    printf(\"\\n\");\n}\n\nint test_t1_t2(void)\n{\n    printf_all_thread_id();\n\n    printf(\"create thread1\\n\");\n    int err = thrd_create(&amp;thread_1, thread1, NULL);\n    if(err!=thrd_success)   \n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread1 failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n    }\n\n    printf(\"create thread2\\n\");\n    err = thrd_create(&amp;thread_2, thread2, NULL);\n    if(err!=thrd_success)   \n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread2 failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n    }\n    \n    thrd_join(thread_2, NULL);\n\n    printf_all_thread_id();\n}\n\n\nint test_t3_t4(void)\n{\n    printf_all_thread_id();\n\n    puts(\"create thread3\");\n    int err = thrd_create(&amp;thread_3, thread3, NULL);\n    if(err!=thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread3 failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n    }\n\n    puts(\"create thread4\");\n    err = thrd_create(&amp;thread_4, thread4, NULL);\n    if(err!=thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread4 failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n    }\n\n    thrd_join(thread_3, NULL);\n    thrd_join(thread_4, NULL);\n    printf_all_thread_id();\n}\n\nint test_t5_t6(void)\n{\n    int err = thrd_create(&amp;thread_5, thread5, NULL);\n    if(err!=thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread5 failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n    }\n    printf(\"thread_5=%ld\\n\", thread_5);\n\n    thrd_join(thread_5, NULL);\n    thrd_join(thread_6, NULL);\n    printf_all_thread_id();\n}\n\nvoid test_t7_t8_mtx_init(void)\n{\n    mtx_init(&amp;mutex_sum, mtx_plain);\n    mutex_sum_ok = true;\n}\n\nvoid test_t7_t8_mtx_destroy(void)\n{\n    mtx_destroy(&amp;mutex_sum);\n    mutex_sum_ok = false;\n}\n\nint test_t7_t8(void)\n{\n    thread7_param_t* param_thread7_1 = calloc(1, sizeof(thread7_param_t));\n    strcpy(param_thread7_1->name, \"thread7_1\");\n    param_thread7_1->run_time_max = 10;\n    param_thread7_1->sleep_time = 300000000;\n\n    int err = thrd_create(&amp;thread_7, thread7, param_thread7_1);\n    if(err!=thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread7 failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n    }\n    printf(\"thread_7=%ld\\n\", thread_7);\n\n\n    thread7_param_t* param_thread7_2 = calloc(1, sizeof(thread7_param_t));\n    strcpy(param_thread7_2->name, \"thread7_2\");\n    param_thread7_2->run_time_max = 10;\n    param_thread7_2->sleep_time = 600000000;\n\n    err = thrd_create(&amp;thread_8, thread7, param_thread7_2);\n    if(err!=thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread8 failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n    }\n    printf(\"thread_8=%ld\\n\", thread_8);\n\n    thrd_join(thread_7, NULL);\n    thrd_join(thread_8, NULL);\n\n    printf_all_thread_id();\n}\n\n\n\n\nint shared_data = 0;\n\nmtx_t mtx_shared_data;\ncnd_t cond_shared_data;\n\nint thread_101(void* param)\n{\n    printf(\"thread_101: start\\n\");\n    \n    mtx_lock(&amp;mtx_shared_data);\n\n    thrd_sleep(&amp;(struct timespec){.tv_sec = 2}, NULL);\n\n    do\n    {\n        cnd_wait(&amp;cond_shared_data, &amp;mtx_shared_data);\n        printf(\"thread_101: woke up, shared_data = %d\\n\", shared_data);\n    } while (shared_data &lt; 1000);\n    \n    printf(\"thread_101: ok, shared_data = %d >= 1000\\n\", shared_data);\n    \n    mtx_unlock(&amp;mtx_shared_data);\n\n    printf(\"thread_101: exit\\n\");\n    \n    thrd_exit(0);\n}\n\nint thread_102(void* param)\n{\n    printf(\"thread_102: start\\n\");\n    \n    mtx_lock(&amp;mtx_shared_data);\n\n    thrd_sleep(&amp;(struct timespec){.tv_sec = 2}, NULL);\n\n    do\n    {\n        cnd_wait(&amp;cond_shared_data, &amp;mtx_shared_data);\n        printf(\"thread_102: woke up, shared_data = %d\\n\", shared_data);\n    } while (shared_data &lt; 800);\n    \n    printf(\"thread_102: ok, shared_data = %d >= 800\\n\", shared_data);\n    \n    mtx_unlock(&amp;mtx_shared_data);\n\n    printf(\"thread_102: exit\\n\");\n    \n    thrd_exit(0);\n}\n\n\nint thread_103(void* param)\n{\n    printf(\"thread_103: start\\n\");\n    \n    mtx_lock(&amp;mtx_shared_data);\n    \n    struct timespec ts;\n    timespec_get(&amp;ts, TIME_UTC);\n    ts.tv_sec += 10;\n    \n    int result = cnd_timedwait(&amp;cond_shared_data, &amp;mtx_shared_data, &amp;ts);\n    \n    if (result == thrd_success)\n    {\n        printf(\"thread_103: got it before timedout, shared_data = %d\\n\", shared_data);\n    }\n    else if (result == thrd_timedout)\n    {\n        printf(\"thread_103: timedout\\n\");\n    }\n    else\n    {\n        printf(\"thread_103: error\\n\");\n    }\n    \n    mtx_unlock(&amp;mtx_shared_data);\n\n    printf(\"thread_103: exit\\n\");\n    \n    thrd_exit(0);\n}\n\n\nvoid make_signal(int data)\n{\n    mtx_lock(&amp;mtx_shared_data);\n    \n    shared_data = data;\n    \n    printf(\"make_signal: send signal to cond_shared_data\\n\");\n    cnd_signal(&amp;cond_shared_data);\n    \n    mtx_unlock(&amp;mtx_shared_data);\n}\n\nint thread_104(void* param)\n{\n    printf(\"thread_104: start\\n\");\n    \n    thrd_sleep(&amp;(struct timespec){.tv_sec = 5}, NULL);\n    \n    for(int i = 1; i &lt; 6; i++)\n    {\n        make_signal(i * 100);\n        thrd_sleep(&amp;(struct timespec){.tv_sec = 1}, NULL);\n    }\n\n    printf(\"thread_104: exit\\n\");\n    \n    thrd_exit(0);\n}\n\n\nvoid make_broadcast(int data)\n{\n    mtx_lock(&amp;mtx_shared_data);\n    \n    shared_data = data;\n    \n    printf(\"make_broadcast: send broadcast to cond_shared_data\\n\");\n    cnd_broadcast(&amp;cond_shared_data);\n    \n    mtx_unlock(&amp;mtx_shared_data);\n}\n\nint thread_105(void* param)\n{\n    printf(\"thread_105: start\\n\");\n    \n    thrd_t t104 = *(thrd_t*)param;\n    thrd_join(t104, NULL);\n\n    printf(\"\\n\\nthread_105: thread_104 joined\\n\");\n    \n    for(int i = 1; i &lt; 12; i++)\n    {\n        make_broadcast(i * 100);\n        thrd_sleep(&amp;(struct timespec){.tv_sec = 1}, NULL);\n    }\n\n    printf(\"thread_105: exit\\n\");\n    \n    thrd_exit(0);\n}\n\n\nint test_cnd_mtx(void)\n{\n    int err = mtx_init(&amp;mtx_shared_data, mtx_plain);\n    if (err != thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create mtx_shared_data failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n        return 1;\n    }\n    \n    err = cnd_init(&amp;cond_shared_data);\n    if (err != thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create cond_shared_data failed:err=%d\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__, err);\n        mtx_destroy(&amp;mtx_shared_data);\n        return 1;\n    }\n    \n    thrd_t t101, t102, t103, t104, t105;\n    \n    if (thrd_create(&amp;t101, thread_101, NULL) != thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread_101 failed\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__);\n        return 1;\n    }\n    \n    if (thrd_create(&amp;t102, thread_102, NULL) != thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread_102 failed\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__);\n        return 1;\n    }\n    \n    if (thrd_create(&amp;t103, thread_103, NULL) != thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread_103 failed\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__);\n        return 1;\n    }\n\n    if (thrd_create(&amp;t104, thread_104, NULL) != thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread_104 failed\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__);\n        return 1;\n    }\n\n    if (thrd_create(&amp;t105, thread_105, &amp;t104) != thrd_success)\n    {\n        printf(\"\\033&#91;31merror:%s,in line %d:create thread_105 failed\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__);\n        return 1;\n    }\n    \n    thrd_join(t101, NULL);\n    thrd_join(t102, NULL);\n    thrd_join(t103, NULL);\n    thrd_join(t104, NULL);\n    thrd_join(t105, NULL);\n\n    cnd_destroy(&amp;cond_shared_data);\n    mtx_destroy(&amp;mtx_shared_data);\n\n    return 0;\n}\n\n\n\n\nthread_local int thread_local_data = 0;\n\ntss_t tss_key_thread201;\ntss_t tss_key_1;\ntss_t tss_key_2;\ntss_t tss_key_3;\n\ntypedef struct\n{\n    char tss_name&#91;64];\n    int tss_value;\n    int tss_data_len;\n    void* tss_data;\n}thread201_tss_t;\n\n\ntypedef struct\n{\n    char name&#91;32];\n    thrd_t thread_id;\n    int set_thread_local_data;\n}thread201_param_t;\n\n\nvoid destroy_data(void* data)\n{\n    thread201_tss_t* p_data = (thread201_tss_t*)data;\n    printf(\"destroy_data: %s, %d, %d, %s\\n\", \\\n        p_data->tss_name, \\\n        p_data->tss_value, \\\n        p_data->tss_data_len, \\\n        (char*)p_data->tss_data);\n    if(data!=NULL)\n    {\n        if(p_data->tss_data!=NULL)\n        {\n            free(p_data->tss_data);\n        }\n        free(data);\n    }\n}\n\n\nint generate_random_string(char **str)\n{\n    if (str == NULL)\n    {\n        return -1;\n    }\n    \n    int length = rand() % 65;\n    \n    *str = (char *)malloc(length + 1);\n    if(*str == NULL)\n    {\n        return -1;\n    }\n    \n    for (int i = 0; i &lt; length; i++)\n    {\n        (*str)&#91;i] = 33 + rand() % 94;\n    }\n    (*str)&#91;length] = '\\0';\n    \n    return length + 1;\n}\n\n\nint thread_201(void* param)\n{\n    thread201_param_t* p_param = (thread201_param_t*)param;\n    thread_local_data = p_param->set_thread_local_data;\n\n    thrd_sleep(&amp;(struct timespec){.tv_sec = 1}, NULL);\n    printf(\"%s: thread_local_data = %d\\n\", p_param->name, thread_local_data);\n    \n\n    thrd_sleep(&amp;(struct timespec){.tv_sec = 1}, NULL);\n\n    thread201_tss_t* tss_data = (thread201_tss_t*)tss_get(tss_key_thread201);\n    if (tss_data == NULL)\n    {\n        tss_data = (thread201_tss_t*)calloc(1, sizeof(thread201_tss_t));\n        if(tss_data==NULL)\n        {\n            printf(\"\\033&#91;31merror:%s,in line %d:calloc tss_data failed\\033&#91;0m\\n\", \\\n                __FILE__, __LINE__);\n            thrd_exit(1);\n        }\n        sprintf(tss_data->tss_name, \"tss_data_%s\", p_param->name);\n        tss_data->tss_value = p_param->set_thread_local_data * 10;\n        tss_data->tss_data_len = generate_random_string((char**)&amp;tss_data->tss_data);\n        \n        tss_set(tss_key_thread201, tss_data);\n        printf(\"%s: set tss_data: %s, %d, %d, %s\\n\", \\\n            p_param->name, \\\n            tss_data->tss_name, \\\n            tss_data->tss_value, \\\n            tss_data->tss_data_len, \\\n            (char*)tss_data->tss_data);\n    }\n    else\n    {\n        printf(\"%s: set tss_data: %s, %d, %d, %s\\n\", \\\n            p_param->name, \\\n            tss_data->tss_name, \\\n            tss_data->tss_value, \\\n            tss_data->tss_data_len, \\\n            (char*)tss_data->tss_data);\n    }\n    \n    tss_data->tss_value += 1;\n    thrd_sleep(&amp;(struct timespec){.tv_sec = 3}, NULL);\n    printf(\"%s: set tss_data: %s, %d, %d, %s\\n\", \\\n        p_param->name, \\\n        tss_data->tss_name, \\\n        tss_data->tss_value, \\\n        tss_data->tss_data_len, \\\n        (char*)tss_data->tss_data);\n\n    printf(\"%s: exit\\n\", p_param->name);\n    thrd_exit(0);\n}\n\n\nint test_tss(void)\n{\n    thread_local_data = 123;\n\n    if (tss_create(&amp;tss_key_thread201, destroy_data) != thrd_success)\n    {\n        printf(\"\\n\");\n        printf(\"\\033&#91;31merror:%s,in line %d:create tss_key_thread201 failed\\n\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__);\n\n        return 1;\n    }\n    printf(\"tss_key_thread201 = %d\\n\", tss_key_thread201);\n    if (tss_create(&amp;tss_key_1, destroy_data) != thrd_success)\n    {\n        printf(\"\\n\");\n        printf(\"\\033&#91;31merror:%s,in line %d:create tss_key_1 failed\\n\\033&#91;0m\\n\", \\\n            __FILE__, __LINE__);\n\n        return 1;\n    }\n    printf(\"tss_key_1 = %d\\n\", tss_key_1);\n    \n    \n    thread201_param_t thread201_params&#91;3];\n    memset(thread201_params, 0, sizeof(thread201_params));\n    for (int i = 0; i &lt; 3; i++)\n    {\n        sprintf(thread201_params&#91;i].name, \"Thread201_%d\", i + 1);\n        thread201_params&#91;i].set_thread_local_data = (i + 1) * 10;\n        \/\/ sprintf(thread201_params&#91;i].tss_data.tss_name, \"tss_data_%d\", i + 1);\n        \/\/ thread201_params&#91;i].tss_data.tss_value = (i + 1) * 100;\n        \/\/ thread201_params&#91;i].tss_data.tss_data = NULL;\n        if (thrd_create(&amp;thread201_params&#91;i].thread_id, thread_201, &amp;thread201_params&#91;i]) != thrd_success)\n        {\n            printf(\"\\033&#91;31merror:%s,in line %d:create thread_201_xx failed\\n\\033&#91;0m\\n\", __FILE__, __LINE__);\n            return 1;\n        }\n    }\n    \n\n    for (int i = 0; i &lt; 3; i++) {\n        thrd_join(thread201_params&#91;i].thread_id, NULL);\n    }\n\n    printf(\"main thread: thread_local_data = %d\\n\", thread_local_data);\n    \n\n    tss_delete(tss_key_thread201);\n    printf(\"tss_key_1 = %d\\n\", tss_key_1);\n\n    if (tss_create(&amp;tss_key_2, destroy_data) != thrd_success)\n    {\n        printf(\"\\n\");\n        printf(\"\\033&#91;31merror:%s,in line %d:create tss_key_2 failed\\n\\033&#91;0m\\n\", __FILE__, __LINE__);\n\n        return 1;\n    }\n    printf(\"tss_key_2 = %d\\n\", tss_key_2);\n\n    if (tss_create(&amp;tss_key_3, destroy_data) != thrd_success)\n    {\n        printf(\"\\n\");\n        printf(\"\\033&#91;31merror:%s,in line %d:create tss_key_3 failed\\n\\033&#91;0m\\n\", __FILE__, __LINE__);\n\n        return 1;\n    }\n    printf(\"tss_key_3 = %d\\n\", tss_key_3);\n\n    tss_delete(tss_key_1);\n    tss_delete(tss_key_2);\n    tss_delete(tss_key_3);\n\n    \n    return 0;\n}\n\n\n\n\nvoid test_thread(int (*func)(void), const char* name)\n{\n    printf(\"\\n===========================================================================\\n\");\n    printf(\"\\033&#91;32m%s\\n\\n\\033&#91;0m\", name);\n    func();\n    printf(\"\\033&#91;32m\\n\\nend test %s\\n\\033&#91;0m\", name);\n    printf(\"===========================================================================\\n\");\n}\n\n\nint main(void)\n{\n    int err = 0;\n\n    test_thread(test_t1_t2, \"test_t1_t2\");\n    test_thread(test_t3_t4, \"test_t3_t4\");\n    test_thread(test_t5_t6, \"test_t5_t6\");\n    test_thread(test_t7_t8, \"test_t7_t8\");\n\n    test_t7_t8_mtx_init();\n    test_thread(test_t7_t8, \"test_t7_t8\");\n    test_t7_t8_mtx_destroy();\n\n    test_thread(test_cnd_mtx, \"test_cnd_mtx\");\n\n    test_thread(test_tss, \"test_tss\");\n\n    \n\treturn 0;\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u6d4b\u8bd5\u4ee3\u7801<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,5],"tags":[],"class_list":["post-726","post","type-post","status-publish","format-standard","hentry","category-c","category-5"],"_links":{"self":[{"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/posts\/726","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/comments?post=726"}],"version-history":[{"count":0,"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/posts\/726\/revisions"}],"wp:attachment":[{"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/media?parent=726"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/categories?post=726"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/niuguodong.com\/index.php\/wp-json\/wp\/v2\/tags?post=726"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}