【发布时间】:2021-06-27 08:44:01
【问题描述】:
我正在处理一项任务,其目标是通过创建多个线程来加快快速排序过程。但是我不知道如何加快这个过程。我应用了开始时允许的线程,但它似乎只会减慢程序的速度?
基本上,目标是使用传统的递归快速排序对简单数组进行排序。但就像我之前所说的那样,只有当我使用 clock() 库来计时它的性能时,它似乎才会减慢它的速度。有什么建议?还是我需要对线程做其他事情?我将在这里上传我的完整源代码:
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <math.h>
#include <sys/wait.h>
#include <assert.h>
#include <time.h>
static int maxThreads = 4;
#define SORT_THRESHOLD 40
//#includes==========
void *blin();
pthread_mutex_t mutex;
void *send(void *);
static int used = 0;
static int reached = 0;
int doit = 0;
int threadNo = 0;
typedef struct _sortParams {
char** array;
int left;
int right;
} SortParams;
static void insertSort(char** array, int left, int right) {
int i, j;
for (i = left + 1; i <= right; i++) {
char* pivot = array[i];
j = i - 1;
while (j >= left && (strcmp(array[j],pivot) > 0)) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = pivot;
}
}
int going = 0;
int blins = 0;
void *send(void * p) {
SortParams* params = (SortParams*) p;
char** array = params->array;
int left = params->left;
int right = params->right;
int i = left, j = right;
if (j - i > SORT_THRESHOLD) {
/* if the sort range is substantial, use quick sort */
int m = (i + j) >> 1; /* pick pivot as median of */
char* temp, *pivot; /* first, last and middle elements */
if (strcmp(array[i],array[m]) > 0) {
temp = array[i]; array[i] = array[m]; array[m] = temp;
}
if (strcmp(array[m],array[j]) > 0) {
temp = array[m]; array[m] = array[j]; array[j] = temp;
if (strcmp(array[i],array[m]) > 0) {
temp = array[i]; array[i] = array[m]; array[m] = temp;
}
}
pivot = array[m];
for (;;) {
while (strcmp(array[i],pivot) < 0) i++;
/* move i down to first element greater than or equal to pivot */
while (strcmp(array[j],pivot) > 0) j--;
/* move j up to first element less than or equal to pivot */
if (i < j) {
char* temp = array[i]; /* if i and j have not passed each other */
array[i++] = array[j]; /* swap their respective elements and */
array[j--] = temp; /* advance both i and j */
} else if (i == j) {
i++; j--;
} else break; /* if i > j, this partitioning is done */
}
if (blins < 1) {
blins++;
SortParams first; first.array = array; first.left = left; first.right = j;
int ex;
pthread_t thred[2];
pthread_create(&thred[0], NULL, send, &first);
pthread_join(thred[0], NULL);
SortParams second; second.array = array; second.left = i; second.right = right;
pthread_create(&thred[1], NULL, send, &second);
pthread_join(thred[1], NULL);
} else {
SortParams first; first.array = array; first.left = left; first.right = j;
send(&first); /* sort the left partition */
SortParams second; second.array = array; second.left = i; second.right = right;
send(&second); /* sort the right partition */
}
} else insertSort(array,i,j); /* for a small range use insert sort */
}
int main() {
int count = 100000;
char * array[count];
char * random[10] = {"asdfs", "wesasd", "asded", "aaddsdaa", "dsfs", "av", "bb",
"zz", "das", "efdxse"};
int r = 0;
for(int ni = 0; ni < count; ni++) {
r = (rand() % 4);
char string[100];
strcpy(string, "");
int b = (rand() % 50)+1;
for (int bb = 0; bb < b; bb++) {
r = (rand() % 4);
if (r == 0) {
strcat(string, "a");
}
if (r == 1) {
strcat(string, "b");
}
if (r == 2) {
strcat(string, "c");
}
if (r == 3) {
strcat(string, "d");
}
if (r == 4) {
strcat(string, "e");
}
}
array[ni] = malloc(sizeof(string));
strcpy(array[ni], string);
}
clock_t t;
t = clock();
SortParams parameters; // declare structure
parameters.array = array; parameters.left = 0; parameters.right = count - 1;
//sleep(5);
send(¶meters);
t = clock() - t;
double total = ((double)t)/CLOCKS_PER_SEC;
printf("%f \n", total);
char ** jink = parameters.array;
for (int ni = 0; ni < count/10; ni++) {
printf("%s \n", jink[ni]);
}
// */
for (int ni = 0; ni < count; ni++) {
free(array[ni]);
} printf("%f \n", total);
return 0;
}
你应该能够简单地复制/粘贴,它应该可以工作,但你可以看到我创建了 2 个线程,但它比没有线程慢。
【问题讨论】:
-
给我一点时间,我马上上传
-
许多因素都列在另一个thread 中。它是关于 C++ 的,但你仍然可以参考它。
-
所以你通过
pthread_create启动一个线程,然后立即等待它以pthread_join结束。这是仅调用相关代码的更昂贵的版本。如果你想要加速,你必须同时启动多个线程,每个线程处理不同的数据,然后等待它们全部完成。 -
我如何立即等待它完成?我怎样才能让它们同时运行并等待它们?
-
@itsMe dratenik 建议使用
create1; join1; create2; join2而不是create1; create2; join1; join2。但是产生太多线程是个坏主意。检查上面 SOFuser 提到的答案。
标签: c linux multithreading