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;
}
有错误的话欢迎修正