(终)c++多线程thread操作(十)多线程并行实现数据相加的和

c++多线程系列

c++多线程thread操作(一)环境部署

c++多线程thread操作(二)线程管理

c++多线程thread操作(三)数据竞争互斥访问

c++多线程thread操作(四)死锁的问题和解决

c++多线程thread操作(五)unique_lock加锁

c++多线程thread操作(六)条件变量的使用

c++多线程thread操作(七)父进程获取子进程变量的结果

c++多线程thread操作(八)父线程传递数据给子线程

c++多线程thread操作(九)可调用方式

(终)c++多线程thread操作(十)多线程并行实现数据相加的和

经过了前面章节内容的学习,下面我们一起来实现一个多线程实现求多个数据相加的和。(这里没有用数组实现,原因在于内存分配给数组的不能有太大空间,N受到限制,不好调试。但是与数组实现方式完全一样!)

假设所要求解的数据长度是N,cpu的核心数是m;

很容易考虑到应将数据尽可能等分给每个cpu运行,故每个cpu运行的数据是:(K_i,K_j)

其中:K_i = $\lceil N/m \rceil$ * i, i = 0,1,..,m-1

$$ K_i=\left\{ \begin{aligned} \lceil N/m \rceil * i, i=0,1,...,m-2\\ N-1 , i = m-1 \\ \end{aligned} \right. $$

其实现代码如下:这里实现获取子线程结果的方式是加入的引用变量;(可以用future变量,很可惜就是不能提速)

#include <iostream>
#include <thread>
using namespace std;
const int N = 2000000000;
void func_2(int begin, int end, int &res) {
	res = 0;
	int sum = 0;
	for (int kk = 1; kk < 10; kk++)
            for (int i = begin; i < end; i++) {
		    sum = (sum + i + 1);
	}
	res = sum;
}
int multi_thread() {
	int cpu_num = thread::hardware_concurrency();//12
	int use_cpu_num = cpu_num;
	int split_num = (N + use_cpu_num - 1) / use_cpu_num;
	int k1 = 0, k2 = split_num;// k1,k2切分数组
	int sum = 0;
	int *res = new int[split_num];
	thread *th = new thread[use_cpu_num];
	for (int i = 0; i < use_cpu_num; i++) {
		th[i] = thread(func_2, k1, k2, ref(res[i]));
		k1 = k2;
		k2 += split_num;
		if (k2 >= N)k2 = N;
	}
	for (int i = 0; i < use_cpu_num; i++)th[i].join();
	for (int i = 0; i < use_cpu_num; i++) {
		sum = (sum + res[i]);
	}
	return sum;
}

int main() {
	long c1 = clock();
	int res;
	func_2(0, N, res);
	long c2 = clock();
	cout << "res = " << res << " , time consume = " << c2 - c1 << endl;

	c1 = clock();
	int sum = multi_thread();
	c2 = clock();
	cout << "sum = " << sum << " , time consume = " << c2 - c1 << endl;

	return 0;
}

运行结果如下:

res 是单线程获取结果;sum是多线程获取结果

Debug模式测试:多线程加速比大约是:800%-900%

1. cpu=12, kk = 10(第八行);

2. cpu=12, kk = 15(第八行)

3. cpu=12, kk = 30(第八行)

Release测试:多线程加速比大约是:400%-500%

1. cpu=12, kk = 10(第八行);

2. cpu=12, kk = 15(第八行)

3. cpu=12, kk = 30(第八行)

 

注:

以上只运行了加法运算,如果运行乘除法,加速比会更高!!

下面是采用了求余运算。

void func_2(int begin, int end, int &res) {
	res = 0;
	int sum = 0;
	for (int kk = 1; kk < 10; kk++)
		for (int i = begin; i < end; i++) {
			sum += (i + 1)%1000;
			sum = sum % 1000;
		}
	res = sum;
}

1. N = 20000000; kk=10

2. N = 200000000;kk=10

  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 C 语言中,可以使用 pthread 库来实现多线程。下面是一个简单的例子,实现了一个数据的收发功能: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> void *send_data(void *arg) { // 发送数据的线程 int *data = (int *)arg; printf("Sending data: %d\n", *data); // TODO: 发送数据操作 return NULL; } void *receive_data(void *arg) { // 接收数据的线程 int *data = (int *)arg; // TODO: 接收数据操作 printf("Received data: %d\n", *data); return NULL; } int main() { pthread_t send_thread, receive_thread; int data = 123; pthread_create(&send_thread, NULL, send_data, &data); pthread_create(&receive_thread, NULL, receive_data, &data); pthread_join(send_thread, NULL); pthread_join(receive_thread, NULL); return 0; } ``` 在这个例子中,我们创建了两个线程,一个用来发送数据,一个用来接收数据数据是通过一个指针传递给线程的,这个指针指向一个 int 类型的变量。在发送数据的线程中,我们打印出要发送的数据,然后执行发送数据操作。在接收数据的线程中,我们执行接收数据操作,然后打印出接收到的数据。 在主函数中,我们使用 pthread_create 函数来创建两个线程,并且传递了数据的指针作为参数。接着,我们使用 pthread_join 函数来等待两个线程执行完毕。最后,我们返回 0,表示程序正常结束。 需要注意的是,在实际的应用中,发送和接收数据操作可能是阻塞的,这时需要使用一些特殊的处理方式来避免线程被阻塞。另外,多线程编程也需要注意线程安全的问题,比如多个线程同时访问同一个共享变量时可能会出现竞态条件等问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值