c - pthreads的多线程调用,排序时不同的结果
问题描述
在下文中,我尝试使用 pthread 对具有多个线程的数组进行排序。这个想法是拆分数组并给每个线程一个部分。shell_sort
它是串行的,而在我的并行尝试中,我每个线程都调用它。
多线程版本与串行结果不匹配(我认为这是正确的),所以我认为我的并行解决方案存在问题,我想寻求帮助。
这main.c
是我的并行尝试:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <pthread.h>
typedef struct {
double *array;
int size;
} data_s;
double *gen_rand(int size, double min, double max) {
srand(time(0));
double *array = malloc(size*sizeof(double));
for(int i = 0; i < size; i++) {
double v = min + rand() / (RAND_MAX/(max-min));
array[i] = floor(v*10)/10;
}
return array;
}
void print(double *array, int size) {
for(int i = 0; i < size; i++)
printf("%.2f ", array[i]);
printf("\n");
}
void swap(double *a, double *b) {
double tmp = *a;
*a = *b;
*b = tmp;
}
void shell_sort(double *array, int size) {
printf("ssort serial\n");
int h = floor(size/2);
while(h >= 1) {
for(int i = h; i < size; i++)
for(int j = i; j >= h && array[j] < array[j-h]; j-=h)
swap(&array[j], &array[j-h]);
h = floor(h/2);
}
}
void *ssort_thread(void *arg) {
printf("ssort parallel\n");
data_s data = *(data_s*)arg;
shell_sort(data.array, data.size);
return 0;
}
void ssort_parallel(double *array, int size, int part) {
int threads = size/part;
pthread_t thread[threads];
for (int i = 0; i < threads; i++) {
print(array+i*part, part);
pthread_create(&thread[i], NULL,
ssort_thread, &(data_s){array+i*part, part});
}
for (int i = 0; i < threads; i++)
pthread_join(thread[i], NULL);
}
int main(int argc, char **argv) {
int array_size = 10;
double *array = gen_rand(array_size, 0, 99);
print(array, array_size);
int threads = 2;
int part = array_size/threads;
ssort_parallel(array, array_size, part);
print(array, array_size);
}
我通过修改ssort_parallel
为:
void ssort_parallel(double *array, int size, int part) {
int threads = size/part;
pthread_t thread[threads];
for (int i = 0; i < threads; i++) {
print(array+i*part, part);
shell_sort(array+i*part, part);
}
}
只是想注意:预期结果不是完整的数组排序。相反,应该对左侧部分和右侧部分进行排序。
这就是我得到的并行:
$ ./main
38.60 11.10 22.00 57.00 31.50 89.10 36.00 79.50 3.80 18.10
38.60 11.10 22.00 57.00 31.50
89.10 36.00 79.50 3.80 18.10
ssort parallel
ssort parallel
ssort serial
ssort serial
38.60 11.10 22.00 57.00 31.50 3.80 18.10 36.00 79.50 89.10
而我得到的串行:
$ ./main
39.10 42.10 98.20 42.40 30.90 88.50 9.40 54.30 9.30 35.40
39.10 42.10 98.20 42.40 30.90
ssort serial
88.50 9.40 54.30 9.30 35.40
ssort serial
30.90 39.10 42.10 42.40 98.20 9.30 9.40 35.40 54.30 88.50
我的感觉是大多数时候右侧是并行正确的。
解决方案
推荐阅读
- javascript - React axios请求请求UseEffect清理函数取消所有订阅和异步任务
- java - Spring MVC 在下一页传递空值
- docker - docker中“清理/清除数据”的命令行等效项是什么?
- java - 我怎样才能获得语言环境的语言?
- php - 创建动态页眉,了解在一次“addPage”操作中创建的 PDF 数量
- r - 如何始终在 geom_bar 中有固定数量的带有缺失值的 bin
- java - 如何使用改造处理布尔中的json对象
- vue.js - 如何从导入的文件中运行另一个 vue.file 中的函数
- c# - 为什么我的内部对象属性名称不是驼峰式的?
- azure-active-directory - 使用单点登录访问 Azure AD 上的多个租户