1-10000中各位数之和为奇数的数的总数

c语言避免数据竞争的一部分方法


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <threads.h>
#include <time.h>
#include <stdatomic.h>

#define N 8

// 原子类型
// atomic_int count = 0;
int count = 0;
mtx_t mtx, mtx1;
// 原子标志类型
atomic_flag aflag = ATOMIC_FLAG_INIT;

// 互斥锁
int count_time(void *arg)
{
    clock_t start_clock = clock();
    mtx_lock(&mtx);
    printf("程序运行时间:%g sec.\n", (clock() - start_clock) / (double)CLOCKS_PER_SEC);
    mtx_unlock(&mtx);
    return 0;
}

// 判断输入是否合理
void is_number(const char *p)
{
    for (; isdigit(*p); p++)
        ;
    if (*p)
    {
        fprintf(stdout, "请输入正确的数字\n");
        exit(EXIT_FAILURE);
    }
}

// 原子类型操作
/* int thread_proc(void *arg)
{
    int a = *(int *)arg, i = 0;
    char arr[N];
    for (; i < 1000; i++)
    {
        sprintf(arr, "%d", a++);
        int char_count = strlen(arr), j = 0, number = 0;
        for (; j < char_count; j++)
        {
            number += arr[j] - 48;
        }
        if (number & 1)
        {
            count += 1;
        }
    }
    return 0;
} */

// 互斥锁
/* int thread_proc(void *arg)
{
    int a = *(int *)arg, i = 0;
    char arr[N];
    for (; i < 1000; i++)
    {
        sprintf(arr, "%d", a++);
        int char_count = strlen(arr), j = 0, number = 0;
        for (; j < char_count; j++)
        {
            number += arr[j] - 48;
        }
        if (number & 1)
        {
            mtx_lock(&mtx1);
            count = count + 1;
            mtx_unlock(&mtx1);
        }
    }
    return 0;
} */

// 原子操作函数
/* int thread_proc(void *arg)
{
    int a = *(int *)arg, i = 0;
    char arr[N];
    for (; i < 1000; i++)
    {
        sprintf(arr, "%d", a++);
        int char_count = strlen(arr), j = 0, number = 0;
        for (; j < char_count; j++)
        {
            number += arr[j] - 48;
        }
        if (number & 1)
        {
            int old = atomic_load(&count), new;
            do
            {
                new = count + 1;
            } while (!atomic_compare_exchange_weak(&count, &old, new));
        }
    }
    return 0;
} */

//  原子操作函数
/* int thread_proc(void *arg)
{
    int a = *(int *)arg, i = 0;
    char arr[N];
    for (; i < 1000; i++)
    {
        sprintf(arr, "%d", a++);
        int char_count = strlen(arr), j = 0, number = 0;
        for (; j < char_count; j++)
        {
            number += arr[j] - 48;
        }
        if (number & 1)
        {
            atomic_fetch_add_explicit(&count, 1, memory_order_release);
        }
    }
    return 0;
} */

// 原子标志类型
int thread_proc(void *arg)
{
    int a = *(int *)arg, i = 0, b = ((int *)arg)[1];
    char arr[N];
    for (; i < b; i++)
    {
        sprintf(arr, "%d", a++);
        int char_count = strlen(arr), j = 0, number = 0;
        for (; j < char_count; j++)
        {
            number += arr[j] - 48;
        }
        if (number & 1)
        {
            while (atomic_flag_test_and_set(&aflag))
                ;
            count = count + 1;
            atomic_flag_clear(&aflag);
        }
    }
    return 0;
}

int main(int argc, char **argv)
{
    is_number(argv[1]);
    div_t ans;
    thrd_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;
    ans = div(atoi(argv[1]), 10);
    int a = ans.quot;

    mtx_init(&mtx, mtx_plain);

    mtx_lock(&mtx);
    thrd_create(&t0, count_time, &(int){0});

    thrd_create(&t1, thread_proc, (int[2]){a * 0, a});
    thrd_create(&t2, thread_proc, (int[2]){a * 1, a});
    thrd_create(&t3, thread_proc, (int[2]){a * 2, a});
    thrd_create(&t4, thread_proc, (int[2]){a * 3, a});
    thrd_create(&t5, thread_proc, (int[2]){a * 4, a});
    thrd_create(&t6, thread_proc, (int[2]){a * 5, a});
    thrd_create(&t7, thread_proc, (int[2]){a * 6, a});
    thrd_create(&t8, thread_proc, (int[2]){a * 7, a});
    thrd_create(&t9, thread_proc, (int[2]){a * 8, a});
    thrd_create(&t10, thread_proc, (int[2]){a * 9, a + (ans.rem ? 0 : 1)});

    thrd_join(t1, &(int){0});
    thrd_join(t2, &(int){0});
    thrd_join(t3, &(int){0});
    thrd_join(t4, &(int){0});
    thrd_join(t5, &(int){0});
    thrd_join(t6, &(int){0});
    thrd_join(t7, &(int){0});
    thrd_join(t8, &(int){0});
    thrd_join(t9, &(int){0});
    thrd_join(t10, &(int){0});

    mtx_unlock(&mtx);
    thrd_join(t0, &(int){0});

    printf("1-%s 共记%d个奇数\n", argv[1], count);

    return 0;
}

有错误的话欢迎修正

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值