#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <stdint.h>
#include <pthread.h>
typedef struct
{
int * array_num;
int count;
bool is_front;
} thread_arg;
#define NUM_COUNT 1000000
#define RANDOM_NUM_MIN 0
#define RANDOM_NUM_MAX 9
uint64_t sum = 0;
uint64_t sum_with_mutex = 0;
uint64_t sum_with_mutex_and_local = 0;
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mtx_with_local = PTHREAD_MUTEX_INITIALIZER;
void get_random_num(int * array_num, int count)
{
srand(time(NULL));
for(int i = 0; i < count; i++)
{
array_num[i] = rand() % (RANDOM_NUM_MAX - RANDOM_NUM_MIN + 1) + RANDOM_NUM_MIN;
}
}
void * thread_function(void * arg)
{
int * array_num = (*(thread_arg *)arg).array_num;
int count = (*(thread_arg *)arg).count;
bool is_front = (*(thread_arg *)arg).is_front;
int start_index = is_front ? 0 : count / 2;
int end_index = is_front ? count / 2 : count;
double center_num = (double)(RANDOM_NUM_MAX + RANDOM_NUM_MIN) / 2;
for(int i = start_index; i < end_index; i++)
{
if(array_num[i] > center_num)
{
sum += array_num[i];
}
}
return NULL;
}
void * thread_function_with_mutex(void * arg)
{
int * array_num = (*(thread_arg *)arg).array_num;
int count = (*(thread_arg *)arg).count;
bool is_front = (*(thread_arg *)arg).is_front;
int start_index = is_front ? 0 : count / 2;
int end_index = is_front ? count / 2 : count;
double center_num = (double)(RANDOM_NUM_MAX + RANDOM_NUM_MIN) / 2;
for(int i = start_index; i < end_index; i++)
{
if(array_num[i] > center_num)
{
if(pthread_mutex_lock(&mtx) != 0)
{
perror("pthread_mutex_lock");
exit(EXIT_FAILURE);
}
sum_with_mutex += array_num[i];
if(pthread_mutex_unlock(&mtx) != 0)
{
perror("pthread_mutex_unlock");
exit(EXIT_FAILURE);
}
}
}
return NULL;
}
void * thread_function_with_mutex_and_local(void * arg)
{
int sum = 0;
int * array_num = (*(thread_arg *)arg).array_num;
int count = (*(thread_arg *)arg).count;
bool is_front = (*(thread_arg *)arg).is_front;
int start_index = is_front ? 0 : count / 2;
int end_index = is_front ? count / 2 : count;
double center_num = (double)(RANDOM_NUM_MAX + RANDOM_NUM_MIN) / 2;
for(int i = start_index; i < end_index; i++)
{
if(array_num[i] > center_num)
{
sum += array_num[i];
}
}
if(pthread_mutex_lock(&mtx_with_local) != 0)
{
perror("pthread_mutex_lock");
exit(EXIT_FAILURE);
}
sum_with_mutex_and_local += sum;
if(pthread_mutex_unlock(&mtx_with_local) != 0)
{
perror("pthread_mutex_unlock");
exit(EXIT_FAILURE);
}
return NULL;
}
uint64_t calculate_sum(int * array_num, int count)
{
uint64_t sum = 0;
double center_num = (double)(RANDOM_NUM_MAX + RANDOM_NUM_MIN) / 2;
for(int i = 0; i < count; i++)
{
if(array_num[i] > center_num)
{
sum += array_num[i];
}
}
return sum;
}
void print_array_num(int * array_num, int count)
{
printf("array:[ ");
for(int i = 0; i < count; i++)
{
printf("%d ", array_num[i]);
}
printf("]\n");
}
int main(void)
{
int count = NUM_COUNT;
// 产生随机数
int * array_num = malloc(sizeof(int) * count);
if(!array_num)
{
perror("malloc");
exit(EXIT_FAILURE);
}
get_random_num(array_num, count);
// 创建线程1,对前半部分符合要求的数据求和
pthread_t child_thread_1;
thread_arg arg1 =
{
.array_num = array_num,
.count = count,
.is_front = true
};
if(pthread_create(&child_thread_1, NULL, thread_function, &arg1) != 0)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 创建线程2,对后半部分符合要求的数据求和
pthread_t child_thread_2;
thread_arg arg2 =
{
.array_num = array_num,
.count = count,
.is_front = false
};
if(pthread_create(&child_thread_2, NULL, thread_function, &arg2) != 0)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 创建线程3,对前半部分符合要求的数据求和,使用互斥量
pthread_t child_thread_3;
thread_arg arg3 =
{
.array_num = array_num,
.count = count,
.is_front = true
};
if(pthread_create(&child_thread_3, NULL, thread_function_with_mutex, &arg3) != 0)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 创建线程4,对后半部分符合要求的数据求和,使用互斥量
pthread_t child_thread_4;
thread_arg arg4 =
{
.array_num = array_num,
.count = count,
.is_front = false
};
if(pthread_create(&child_thread_4, NULL, thread_function_with_mutex, &arg4) != 0)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 创建线程5,对前半部分符合要求的数据求和,使用互斥量和局部变量
pthread_t child_thread_5;
thread_arg arg5 =
{
.array_num = array_num,
.count = count,
.is_front = true
};
if(pthread_create(&child_thread_5, NULL, thread_function_with_mutex_and_local, &arg5) != 0)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 创建线程6,对后半部分符合要求的数据求和,使用互斥量和局部变量
pthread_t child_thread_6;
thread_arg arg6 =
{
.array_num = array_num,
.count = count,
.is_front = false
};
if(pthread_create(&child_thread_6, NULL, thread_function_with_mutex_and_local, &arg6) != 0)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 主线程在此等待所有背景线程结束
if(pthread_join(child_thread_1, NULL) != 0)
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
if(pthread_join(child_thread_2, NULL) != 0)
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
if(pthread_join(child_thread_3, NULL) != 0)
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
if(pthread_join(child_thread_4, NULL) != 0)
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
if(pthread_join(child_thread_5, NULL) != 0)
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
if(pthread_join(child_thread_6, NULL) != 0)
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
printf("[Task #2] Calculate sum by thread: %lu\n", sum);
printf("[Task #2] Calculate sum accurately: %lu\n", calculate_sum(array_num, count));
printf("[Task #3] Calculate sum by thread with mutex: %lu\n", sum_with_mutex);
printf("[Task #4] Calculate sum by thread with mutex and local variable: %lu\n", sum_with_mutex_and_local);
return EXIT_SUCCESS;
}
[代码实例][C]Linux多线程编程示例
最新推荐文章于 2022-07-15 17:40:18 发布