99999

#include<stdio.h>
#include<stdlib.h>
#include<sys/time.h>
#include<pthread.h>

#define N 10000
#define THREAD_SIZE 8
#define MAX_DEPTH 32

int a[N];


void createarray(int a[]){
    srand((unsigned)(20230427));
    for(int i=0;i<N;i++){
        a[i]=rand()%1001;
    }
    return ;
}

void print(int a1[]){
    int mmmm = N>100?100:N;
    printf("[ ");
    for (int i = 0; i < mmmm-1; i++) {
        printf("%3d , ", a1[i]);
        if (i % 10 == 9) { printf("\n  "); }
    }
    if(N>mmmm){printf("%3d ,\n  ... ...  ]\n---!数组元素个数为:%d,我们仅展示了前100项。!---\n",a1[mmmm-1],N);}
    else{printf("%3d  ]\n",a1[mmmm-1]);}
    return;
}

void quicksort1(void * aptr);
void * quicksort2(void * aptr);


struct  PARM{
    int lowerbound;
    int upperbound;
    int* arr;
};


typedef struct {
    struct PARM tasks[N];
    size_t count;
    pthread_mutex_t lock;
    pthread_cond_t notify;
} TaskQueue;


void push_task(TaskQueue *queue, struct PARM task) {
    pthread_mutex_lock(&queue->lock);
    queue->tasks[queue->count++] = task;
    pthread_cond_signal(&queue->notify);
    pthread_mutex_unlock(&queue->lock);
}


struct PARM pop_task(TaskQueue *queue) {
    struct PARM task;
    pthread_mutex_lock(&queue->lock);
    while (queue->count == 0)
    {
        pthread_cond_wait(&queue->notify, &queue->lock);
    }

    task = queue->tasks[--queue->count];

    pthread_mutex_unlock(&queue->lock);
    return task;
}

TaskQueue queue;
pthread_t threads[THREAD_SIZE];


void *worker(void *arg) {
    struct PARM task;

    while(1) {
        task = pop_task(&queue);
        if(task.arr == NULL)
        {
            break;
        }
        if(task.lowerbound >= task.upperbound)
        {
            continue;
        }
        if(task.upperbound - task.lowerbound > MAX_DEPTH) {

            int pivot,left,right,temp;
            pivot = task.arr[task.lowerbound];
            left = task.lowerbound;
            right = task.upperbound;
            int * a = task.arr;

            while (left < right) {
                while (a[right] >= pivot && left < right) {
                    right--;
                }
                while (a[left] <= pivot&&left<right){
                    left++;
                }
                if (left < right) {
                    temp = a[left];
                    a[left] = a[right];
                    a[right] = temp;
                }
            }

            a[task.lowerbound] = a[left];
            a[left] = pivot;

            struct PARM left_task = {task.lowerbound, left - 1,task.arr}, right_task = { left + 1, task.upperbound,task.arr};
            push_task(&queue, left_task);
            push_task(&queue, right_task);
        } else{
            quicksort1((void *)&task);
        }

    }

    return NULL;
}

int main(int argc,char *argv[]){
    struct timeval start1,end1,start2,end2,start3,end3;
    long seconds1,useconds1,seconds2,useconds2,seconds3,useconds3;
    double mtime1,mtime2,mtime3;
    struct PARM arg;
    arg.upperbound=N-1;
    arg.lowerbound=0;
    createarray(a);
    arg.arr = a;
    printf("\n****************************串行快排*************************\n\n");
    printf("未排序数组\n");
    print(a);

    gettimeofday(&start1,NULL);
    quicksort1((void *)&arg);
    gettimeofday(&end1,NULL);

    printf("排序数组:\n");
    print(a);
    createarray(a);
    printf("\n****************************多线程快排*************************\n\n");
    pthread_t me,thread;
    me = pthread_self();
    printf("主线程(%lu):未排序数组:\n",me);
    print(a);

    gettimeofday(&start2,NULL);
    pthread_create (&thread,NULL,quicksort2,(void *)&arg);
    pthread_join(thread,NULL);
    gettimeofday(&end2,NULL);

    printf("主线程(%lu):排序数组:\n",me);
    print(a);
    createarray(a);
    printf("\n****************************线程池快排*************************\n\n");
    printf("未排序数组:\n");
    print(a);
    queue.count = 0;

    gettimeofday(&start3,NULL);
    pthread_mutex_init(&queue.lock, NULL);
    pthread_cond_init(&queue.notify, NULL);

    arg.upperbound=N-1;arg.lowerbound=0;
    push_task(&queue, arg);

    for(int i=0; i<THREAD_SIZE; i++){
        pthread_create(&threads[i], NULL, worker, NULL);
    }

    for(int i=0; i<THREAD_SIZE; i++){
        push_task(&queue, (struct PARM){.arr=NULL});
    }

    for(int i=0; i<THREAD_SIZE; i++){
        pthread_join(threads[i], NULL);
    }
    gettimeofday(&end3,NULL);
    printf("排序数组:\n");
    print(a);
    seconds1=end1.tv_sec-start1.tv_sec;
    useconds1 = end1.tv_usec-start1.tv_usec;
    mtime1 = seconds1*1000+useconds1/1000.0;
    seconds2=end2.tv_sec-start2.tv_sec;
    useconds2 = end2.tv_usec-start2.tv_usec;
    mtime2 = seconds2*1000+useconds2/1000.0;
    seconds3=end3.tv_sec-start3.tv_sec;
    useconds3 = end3.tv_usec-start3.tv_usec;
    mtime3 = seconds3*1000+useconds3/1000.0;
    printf("\n串行快排程序运行了:%.3f毫秒;\nLinux多线程快排程序运行了:%.3f毫秒;\n使用线程池的Linux快排程序运行了:%.3f毫秒;\n",mtime1,mtime2,mtime3);
    printf("Linux多线程快速排序与串行快速排序相比,加速比为%.6f\n",mtime1/mtime2);
    printf("使用线程池与不使用线程池的Linux并行快速排序相比,加速比为%.6f\n",mtime2/mtime3);
    return 0;
}

void quicksort1(void* aptr){
    struct PARM* ap, aleft, aright;
    ap = (struct PARM*)aptr;
    int pivot, pivotIndex, left, right, temp;
    int upperbound, lowerbound;
    upperbound = ap->upperbound;
    lowerbound = ap->lowerbound;
    int* a = ap->arr;

    if (lowerbound >= upperbound)
    {
        return;
    }

    pivot = a[lowerbound];
    left = lowerbound;
    right = upperbound;

    while (left < right) {
        while (a[right] >= pivot && left < right)
        {
            right--;
        }
        while (a[left] <= pivot&&left<right)
        {
            left++;
        }
        if (left < right)
        {
            temp = a[left];
            a[left] = a[right];
            a[right] = temp;
        }
    }

    a[lowerbound] = a[left];
    a[left] = pivot;
    pivotIndex = left;
    aleft.upperbound = pivotIndex - 1;
    aleft.lowerbound = lowerbound;
    aleft.arr = a;
    aright.upperbound = upperbound;
    aright.lowerbound = pivotIndex + 1;
    aright.arr = a;
    quicksort1((void*)&aleft);
    quicksort1((void*)&aright);

    return;
}

void * quicksort2(void *aptr){
    struct PARM* ap, aleft, aright;
    ap = (struct PARM*)aptr;
    int pivot, pivotIndex, left, right, temp;
    int upperbound, lowerbound;
    upperbound = ap->upperbound;
    lowerbound = ap->lowerbound;
    int* a = ap->arr;

    if (lowerbound >= upperbound)
    {
        return NULL;
    }

    pivot = a[lowerbound];
    left = lowerbound;
    right = upperbound;

    while (left < right) {
        while (a[right] >= pivot && left < right)
        {
            right--;
        }
        while (a[left] <= pivot&&left<right)
        {
            left++;
        }
        if (left < right)
        {
            temp = a[left];
            a[left] = a[right];
            a[right] = temp;
        }
    }

    a[lowerbound] = a[left];
    a[left] = pivot;
    pivotIndex = left;
    aleft.upperbound = pivotIndex - 1;
    aleft.lowerbound = lowerbound;
    aleft.arr = a;
    aright.upperbound = upperbound;
    aright.lowerbound = pivotIndex + 1;
    aright.arr = a;

    pthread_t leftThread,rightThread;
    pthread_create(&leftThread,NULL,quicksort2,(void *)&aleft);
    pthread_join(leftThread,NULL);
    pthread_create(&rightThread,NULL,quicksort2,(void *)&aright);

    pthread_join(rightThread,NULL);


    return NULL;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值