C语言多线程测试

测试代码

#include <stdio.h>
#include <threads.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "unistd.h"


thrd_t thread_1 = 0;
thrd_t thread_2 = 0;
thrd_t thread_3 = 0;
thrd_t thread_4 = 0;
thrd_t thread_5 = 0;
thrd_t thread_6 = 0;
thrd_t thread_7 = 0;
thrd_t thread_8 = 0;

int thread1(void* param)
{
    puts("thread1 start");

    int run_time = 0;
    while(1)
    {
        run_time++;
        sleep(1);
        printf("thread1:run_time=%d\n",run_time);
        if(run_time==5)
        {
            thrd_exit(123);
            puts("thread1 exit.");  //不会执行
        }
    }
}


int thread2(void* param)
{
    puts("thread2 start");
    int thread1_result = 0;

    int run_time = 0;
    while(1)
    {
        run_time++;
        sleep(1);
        printf("thread2:run_time=%d\n",run_time);
        if(run_time==3)
        {
            puts("thread2:thrd_join(thread_1, &thread1_result)");
            int err = thrd_join(thread_1, &thread1_result);
            printf("err=%d\n", err);
            printf("thread1_result=%d\n", thread1_result);
        }
        if(run_time==6)
        {
            puts("thread2 exit.");
            thrd_exit(0);
            puts("thread2 exited.");    //不会执行
        }
    }
}


int thread3(void* param)
{
    puts("thread3 start");
    int thread1_result = 0;

    int run_time = 0;
    while(1)
    {
        run_time++;
        sleep(1);
        printf("thread3:run_time=%d\n",run_time);
        if(run_time==5)
        {
            thrd_t curthr_id = thrd_current();
            if(thrd_equal(curthr_id, thread_3))
            {
                printf("thread3: curthr_id equal thread_3\n");
            }
            printf("thread3:curthr_id=%ld\n", curthr_id);
        }
        if(run_time==6)
        {
            puts("thread3 exit.");
            thrd_exit(0);
        }
    }
}


int thread4(void* param)
{
    puts("thread4 start");
    int thread1_result = 0;

    int run_time = 0;
    while(1)
    {
        run_time++;
        sleep(1);
        printf("thread4:run_time=%d\n",run_time);
        if(run_time==3)
        {
            puts("thread4:thrd_detach(thread_3)");
            int err = thrd_detach(thread_3);    //分离线程3, 使其资源在线程结束后自动释放
            printf("err=%d\n", err);
        }
        if(run_time==8)
        {
            puts("thread4 exit.");
            thrd_exit(0);
        }
    }
}


int thread6(void* param)
{
    puts("thread6 start");

    int run_time = 0;
    while(1)
    {
        run_time++;
        sleep(1);
        printf("thread6:run_time=%d\n",run_time);
        if(run_time==5)
        {
            puts("thread6 exit.");
            thrd_exit(0);
        }
    }
}


int thread5(void* param)
{
    puts("thread5 ok");
    int thread1_result = 0;

    int run_time = 0;
    while(1)
    {
        run_time++;
        sleep(1);
        printf("thread5:run_time=%d\n",run_time);
        if(run_time==3)
        {
            thrd_t curthr_id = thrd_current();
            printf("thread5:curthr_id=%ld\n", curthr_id);
            printf("Time: %s", ctime(&(time_t){time(NULL)}));
            thrd_sleep(&(struct timespec){.tv_sec=5}, NULL);
            printf("Time: %s", ctime(&(time_t){time(NULL)}));
        }
        if(run_time==6)
        {
            int err = thrd_create(&thread_6, thread6, NULL);
            if(err!=thrd_success)   
            {
                printf("\033[31merror:%s,in line %d:create thread6 failed:err=%d\033[0m\n", \
                    __FILE__, __LINE__, err);
            }
        }
        if(run_time==8)
        {
            puts("thread5 exit.");
            thrd_exit(0);
        }
    }
}


typedef struct
{
    char name[32];
    int run_time_max;
    int sleep_time;
}thread7_param_t;

mtx_t mutex_sum;
bool mutex_sum_ok = false;

static int test_sum(const char* t_name, int runtime, int a, int b)
{
    static int c = 0;
    if(mutex_sum_ok)
    {
        mtx_lock(&mutex_sum);
    }
    c++;
    int d = a + b + c;
    printf("%s, test_sum(start%d): a=%d, b=%d, c=%d\n", t_name, runtime, a, b, c);
    if(a>=100)
    {
        thrd_sleep(&(struct timespec){.tv_nsec=500000000}, NULL);
    }

    printf("%s, test_sum(end%d): a=%d, b=%d, c=%d\n", t_name, runtime, a, b, c);

    int ret = a+b+c;
    if(mutex_sum_ok)
    {
        mtx_unlock(&mutex_sum);
    }
    
    if(ret!=d)
    {
        printf("\033[31merror:%s,in line %d: %s, test_sum(%d) result error:ret=%d, d=%d\033[0m\n", \
            __FILE__, __LINE__, t_name, runtime, ret, d);
    }
    return ret;
}

int thread7(void* param)
{
    thread7_param_t* p_param = (thread7_param_t*)param;
    printf("%s start\n", p_param->name);
    printf("%s: sleep_time=%d ns\n", p_param->name, p_param->sleep_time);

    int run_time = 0;
    while(1)
    {
        run_time++;
        thrd_sleep(&(struct timespec){.tv_nsec=p_param->sleep_time}, NULL);
        printf("%s:run_time=%d\n", p_param->name, run_time);

        int sum = test_sum(p_param->name, run_time, run_time*30, 1);
        printf("%s: sum=%d\n", p_param->name, sum);

        if(run_time==p_param->run_time_max)
        {
            printf("%s exit.\n", p_param->name);
            thrd_exit(0);
        }
    }
}

void printf_all_thread_id(void)
{
    printf("All thread id:\n");
    printf("thread_1=%ld, thread_2=%ld\n", thread_1, thread_2);
    printf("thread_3=%ld, thread_4=%ld\n", thread_3, thread_4);
    printf("thread_5=%ld, thread_6=%ld\n", thread_5, thread_6);
    printf("thread_7=%ld, thread_8=%ld\n", thread_7, thread_8);
    printf("\n");
}

int test_t1_t2(void)
{
    printf_all_thread_id();

    printf("create thread1\n");
    int err = thrd_create(&thread_1, thread1, NULL);
    if(err!=thrd_success)   
    {
        printf("\033[31merror:%s,in line %d:create thread1 failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
    }

    printf("create thread2\n");
    err = thrd_create(&thread_2, thread2, NULL);
    if(err!=thrd_success)   
    {
        printf("\033[31merror:%s,in line %d:create thread2 failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
    }
    
    thrd_join(thread_2, NULL);

    printf_all_thread_id();
}


int test_t3_t4(void)
{
    printf_all_thread_id();

    puts("create thread3");
    int err = thrd_create(&thread_3, thread3, NULL);
    if(err!=thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread3 failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
    }

    puts("create thread4");
    err = thrd_create(&thread_4, thread4, NULL);
    if(err!=thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread4 failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
    }

    thrd_join(thread_3, NULL);
    thrd_join(thread_4, NULL);
    printf_all_thread_id();
}

int test_t5_t6(void)
{
    int err = thrd_create(&thread_5, thread5, NULL);
    if(err!=thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread5 failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
    }
    printf("thread_5=%ld\n", thread_5);

    thrd_join(thread_5, NULL);
    thrd_join(thread_6, NULL);
    printf_all_thread_id();
}

void test_t7_t8_mtx_init(void)
{
    mtx_init(&mutex_sum, mtx_plain);
    mutex_sum_ok = true;
}

void test_t7_t8_mtx_destroy(void)
{
    mtx_destroy(&mutex_sum);
    mutex_sum_ok = false;
}

int test_t7_t8(void)
{
    thread7_param_t* param_thread7_1 = calloc(1, sizeof(thread7_param_t));
    strcpy(param_thread7_1->name, "thread7_1");
    param_thread7_1->run_time_max = 10;
    param_thread7_1->sleep_time = 300000000;

    int err = thrd_create(&thread_7, thread7, param_thread7_1);
    if(err!=thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread7 failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
    }
    printf("thread_7=%ld\n", thread_7);


    thread7_param_t* param_thread7_2 = calloc(1, sizeof(thread7_param_t));
    strcpy(param_thread7_2->name, "thread7_2");
    param_thread7_2->run_time_max = 10;
    param_thread7_2->sleep_time = 600000000;

    err = thrd_create(&thread_8, thread7, param_thread7_2);
    if(err!=thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread8 failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
    }
    printf("thread_8=%ld\n", thread_8);

    thrd_join(thread_7, NULL);
    thrd_join(thread_8, NULL);

    printf_all_thread_id();
}




int shared_data = 0;

mtx_t mtx_shared_data;
cnd_t cond_shared_data;

int thread_101(void* param)
{
    printf("thread_101: start\n");
    
    mtx_lock(&mtx_shared_data);

    thrd_sleep(&(struct timespec){.tv_sec = 2}, NULL);

    do
    {
        cnd_wait(&cond_shared_data, &mtx_shared_data);
        printf("thread_101: woke up, shared_data = %d\n", shared_data);
    } while (shared_data < 1000);
    
    printf("thread_101: ok, shared_data = %d >= 1000\n", shared_data);
    
    mtx_unlock(&mtx_shared_data);

    printf("thread_101: exit\n");
    
    thrd_exit(0);
}

int thread_102(void* param)
{
    printf("thread_102: start\n");
    
    mtx_lock(&mtx_shared_data);

    thrd_sleep(&(struct timespec){.tv_sec = 2}, NULL);

    do
    {
        cnd_wait(&cond_shared_data, &mtx_shared_data);
        printf("thread_102: woke up, shared_data = %d\n", shared_data);
    } while (shared_data < 800);
    
    printf("thread_102: ok, shared_data = %d >= 800\n", shared_data);
    
    mtx_unlock(&mtx_shared_data);

    printf("thread_102: exit\n");
    
    thrd_exit(0);
}


int thread_103(void* param)
{
    printf("thread_103: start\n");
    
    mtx_lock(&mtx_shared_data);
    
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    ts.tv_sec += 10;
    
    int result = cnd_timedwait(&cond_shared_data, &mtx_shared_data, &ts);
    
    if (result == thrd_success)
    {
        printf("thread_103: got it before timedout, shared_data = %d\n", shared_data);
    }
    else if (result == thrd_timedout)
    {
        printf("thread_103: timedout\n");
    }
    else
    {
        printf("thread_103: error\n");
    }
    
    mtx_unlock(&mtx_shared_data);

    printf("thread_103: exit\n");
    
    thrd_exit(0);
}


void make_signal(int data)
{
    mtx_lock(&mtx_shared_data);
    
    shared_data = data;
    
    printf("make_signal: send signal to cond_shared_data\n");
    cnd_signal(&cond_shared_data);
    
    mtx_unlock(&mtx_shared_data);
}

int thread_104(void* param)
{
    printf("thread_104: start\n");
    
    thrd_sleep(&(struct timespec){.tv_sec = 5}, NULL);
    
    for(int i = 1; i < 6; i++)
    {
        make_signal(i * 100);
        thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);
    }

    printf("thread_104: exit\n");
    
    thrd_exit(0);
}


void make_broadcast(int data)
{
    mtx_lock(&mtx_shared_data);
    
    shared_data = data;
    
    printf("make_broadcast: send broadcast to cond_shared_data\n");
    cnd_broadcast(&cond_shared_data);
    
    mtx_unlock(&mtx_shared_data);
}

int thread_105(void* param)
{
    printf("thread_105: start\n");
    
    thrd_t t104 = *(thrd_t*)param;
    thrd_join(t104, NULL);

    printf("\n\nthread_105: thread_104 joined\n");
    
    for(int i = 1; i < 12; i++)
    {
        make_broadcast(i * 100);
        thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);
    }

    printf("thread_105: exit\n");
    
    thrd_exit(0);
}


int test_cnd_mtx(void)
{
    int err = mtx_init(&mtx_shared_data, mtx_plain);
    if (err != thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create mtx_shared_data failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
        return 1;
    }
    
    err = cnd_init(&cond_shared_data);
    if (err != thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create cond_shared_data failed:err=%d\033[0m\n", \
            __FILE__, __LINE__, err);
        mtx_destroy(&mtx_shared_data);
        return 1;
    }
    
    thrd_t t101, t102, t103, t104, t105;
    
    if (thrd_create(&t101, thread_101, NULL) != thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread_101 failed\033[0m\n", \
            __FILE__, __LINE__);
        return 1;
    }
    
    if (thrd_create(&t102, thread_102, NULL) != thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread_102 failed\033[0m\n", \
            __FILE__, __LINE__);
        return 1;
    }
    
    if (thrd_create(&t103, thread_103, NULL) != thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread_103 failed\033[0m\n", \
            __FILE__, __LINE__);
        return 1;
    }

    if (thrd_create(&t104, thread_104, NULL) != thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread_104 failed\033[0m\n", \
            __FILE__, __LINE__);
        return 1;
    }

    if (thrd_create(&t105, thread_105, &t104) != thrd_success)
    {
        printf("\033[31merror:%s,in line %d:create thread_105 failed\033[0m\n", \
            __FILE__, __LINE__);
        return 1;
    }
    
    thrd_join(t101, NULL);
    thrd_join(t102, NULL);
    thrd_join(t103, NULL);
    thrd_join(t104, NULL);
    thrd_join(t105, NULL);

    cnd_destroy(&cond_shared_data);
    mtx_destroy(&mtx_shared_data);

    return 0;
}




thread_local int thread_local_data = 0;

tss_t tss_key_thread201;
tss_t tss_key_1;
tss_t tss_key_2;
tss_t tss_key_3;

typedef struct
{
    char tss_name[64];
    int tss_value;
    int tss_data_len;
    void* tss_data;
}thread201_tss_t;


typedef struct
{
    char name[32];
    thrd_t thread_id;
    int set_thread_local_data;
}thread201_param_t;


void destroy_data(void* data)
{
    thread201_tss_t* p_data = (thread201_tss_t*)data;
    printf("destroy_data: %s, %d, %d, %s\n", \
        p_data->tss_name, \
        p_data->tss_value, \
        p_data->tss_data_len, \
        (char*)p_data->tss_data);
    if(data!=NULL)
    {
        if(p_data->tss_data!=NULL)
        {
            free(p_data->tss_data);
        }
        free(data);
    }
}


int generate_random_string(char **str)
{
    if (str == NULL)
    {
        return -1;
    }
    
    int length = rand() % 65;
    
    *str = (char *)malloc(length + 1);
    if(*str == NULL)
    {
        return -1;
    }
    
    for (int i = 0; i < length; i++)
    {
        (*str)[i] = 33 + rand() % 94;
    }
    (*str)[length] = '\0';
    
    return length + 1;
}


int thread_201(void* param)
{
    thread201_param_t* p_param = (thread201_param_t*)param;
    thread_local_data = p_param->set_thread_local_data;

    thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);
    printf("%s: thread_local_data = %d\n", p_param->name, thread_local_data);
    

    thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);

    thread201_tss_t* tss_data = (thread201_tss_t*)tss_get(tss_key_thread201);
    if (tss_data == NULL)
    {
        tss_data = (thread201_tss_t*)calloc(1, sizeof(thread201_tss_t));
        if(tss_data==NULL)
        {
            printf("\033[31merror:%s,in line %d:calloc tss_data failed\033[0m\n", \
                __FILE__, __LINE__);
            thrd_exit(1);
        }
        sprintf(tss_data->tss_name, "tss_data_%s", p_param->name);
        tss_data->tss_value = p_param->set_thread_local_data * 10;
        tss_data->tss_data_len = generate_random_string((char**)&tss_data->tss_data);
        
        tss_set(tss_key_thread201, tss_data);
        printf("%s: set tss_data: %s, %d, %d, %s\n", \
            p_param->name, \
            tss_data->tss_name, \
            tss_data->tss_value, \
            tss_data->tss_data_len, \
            (char*)tss_data->tss_data);
    }
    else
    {
        printf("%s: set tss_data: %s, %d, %d, %s\n", \
            p_param->name, \
            tss_data->tss_name, \
            tss_data->tss_value, \
            tss_data->tss_data_len, \
            (char*)tss_data->tss_data);
    }
    
    tss_data->tss_value += 1;
    thrd_sleep(&(struct timespec){.tv_sec = 3}, NULL);
    printf("%s: set tss_data: %s, %d, %d, %s\n", \
        p_param->name, \
        tss_data->tss_name, \
        tss_data->tss_value, \
        tss_data->tss_data_len, \
        (char*)tss_data->tss_data);

    printf("%s: exit\n", p_param->name);
    thrd_exit(0);
}


int test_tss(void)
{
    thread_local_data = 123;

    if (tss_create(&tss_key_thread201, destroy_data) != thrd_success)
    {
        printf("\n");
        printf("\033[31merror:%s,in line %d:create tss_key_thread201 failed\n\033[0m\n", \
            __FILE__, __LINE__);

        return 1;
    }
    printf("tss_key_thread201 = %d\n", tss_key_thread201);
    if (tss_create(&tss_key_1, destroy_data) != thrd_success)
    {
        printf("\n");
        printf("\033[31merror:%s,in line %d:create tss_key_1 failed\n\033[0m\n", \
            __FILE__, __LINE__);

        return 1;
    }
    printf("tss_key_1 = %d\n", tss_key_1);
    
    
    thread201_param_t thread201_params[3];
    memset(thread201_params, 0, sizeof(thread201_params));
    for (int i = 0; i < 3; i++)
    {
        sprintf(thread201_params[i].name, "Thread201_%d", i + 1);
        thread201_params[i].set_thread_local_data = (i + 1) * 10;
        // sprintf(thread201_params[i].tss_data.tss_name, "tss_data_%d", i + 1);
        // thread201_params[i].tss_data.tss_value = (i + 1) * 100;
        // thread201_params[i].tss_data.tss_data = NULL;
        if (thrd_create(&thread201_params[i].thread_id, thread_201, &thread201_params[i]) != thrd_success)
        {
            printf("\033[31merror:%s,in line %d:create thread_201_xx failed\n\033[0m\n", __FILE__, __LINE__);
            return 1;
        }
    }
    

    for (int i = 0; i < 3; i++) {
        thrd_join(thread201_params[i].thread_id, NULL);
    }

    printf("main thread: thread_local_data = %d\n", thread_local_data);
    

    tss_delete(tss_key_thread201);
    printf("tss_key_1 = %d\n", tss_key_1);

    if (tss_create(&tss_key_2, destroy_data) != thrd_success)
    {
        printf("\n");
        printf("\033[31merror:%s,in line %d:create tss_key_2 failed\n\033[0m\n", __FILE__, __LINE__);

        return 1;
    }
    printf("tss_key_2 = %d\n", tss_key_2);

    if (tss_create(&tss_key_3, destroy_data) != thrd_success)
    {
        printf("\n");
        printf("\033[31merror:%s,in line %d:create tss_key_3 failed\n\033[0m\n", __FILE__, __LINE__);

        return 1;
    }
    printf("tss_key_3 = %d\n", tss_key_3);

    tss_delete(tss_key_1);
    tss_delete(tss_key_2);
    tss_delete(tss_key_3);

    
    return 0;
}




void test_thread(int (*func)(void), const char* name)
{
    printf("\n===========================================================================\n");
    printf("\033[32m%s\n\n\033[0m", name);
    func();
    printf("\033[32m\n\nend test %s\n\033[0m", name);
    printf("===========================================================================\n");
}


int main(void)
{
    int err = 0;

    test_thread(test_t1_t2, "test_t1_t2");
    test_thread(test_t3_t4, "test_t3_t4");
    test_thread(test_t5_t6, "test_t5_t6");
    test_thread(test_t7_t8, "test_t7_t8");

    test_t7_t8_mtx_init();
    test_thread(test_t7_t8, "test_t7_t8");
    test_t7_t8_mtx_destroy();

    test_thread(test_cnd_mtx, "test_cnd_mtx");

    test_thread(test_tss, "test_tss");

    
	return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
error: Content is protected !!