[代码实例][C]Linux多线程编程示例

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值