程序描述
此程序实现了多线程的数组排序,可将一个数组拆分为两部分交由两个线程来排序,最后由父进程对其总和。
程序功能实现代码预览
定义一个结构来存排序算法所需要的参数
typedef struct //结构体用来存排序算法需要的参数
{
int start;
int end;
}Para;
一个简单的冒泡排序
void sort(Para* para){
int i,j,temp;
for(i=para->start;i<para->end;i++){
for(j=para->end;j>i;j--){
if(elem[j]<elem[j-1]){
temp=elem[j];
elem[j]=elem[j-1];
elem[j-1]=temp;
}
}
}
pthread_exit(0);
}
实现对程序计时
int t_start=clock();
int t_end=clock();
将上面的代码分别放在程序首尾,最后相减即可得出运行时间
printf("耗时:%d\n", t_end-t_start);
注:此时间为CPU时间,两个核的话会把两个核的时间加起来。可以在程序名前面加time即可最后得出各种运行时间。
time ./a.out
创建两个线程
pthread_t tid1,tid2; //线程的identifier
pthread_attr_t attr; //线程属性
pthread_attr_init(&attr); //初始化默认线程属性
/**
* 创建执行线程
*/
pthread_create(&tid1,&attr,(void *)sort,¶1);
pthread_create(&tid2,&attr,(void *)sort,¶2);
重难点解析
关于gcc编译
由于pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()创建线程,以及调用 pthread_atfork()函数建立fork处理程序时,需要链接该库。
gcc ./MultithreadsSort.c -lpthread
关于pthread_create
在使用这个方法时,第四个参数非常容易报错,原因是其为void * 类型,所以定义此类方法时参数要定义为void * 类型,然后再在方法中对参数进行格式转换。
void *sort(void * p){
Para * para=(Para*)p;
...
}
完整代码
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#define LENGTH 5000 //宏定义数组长度
#define MAX 100000 //宏定义数取值范围
typedef struct //结构体用来存排序算法需要的参数
{
int start;
int end;
}Para;
int elem[LENGTH]; //存随机数
int res[LENGTH]; //存排序结果
void initElem(); //初始化数组,向其中填指定范围的随机数
void *sort(void * p); //排序程序
void printElenm(int [LENGTH]); //打印数组用以检验是否排序成功
void merge(); //将elem的结果merge到res中
int main(){
initElem(); //初始化数组并填入随机数
/**
* 设定两个线程各自排序的起止点
*/
Para para1={0,LENGTH/2};
Para para2={LENGTH/2+1,LENGTH-1};
Para para3={0,LENGTH-1};
pthread_t tid1,tid2; //线程的identifier
pthread_attr_t attr; //线程属性
pthread_attr_init(&attr); //初始化默认线程属性
int t_start=clock(); //开始时间
printf("多线程排序%d 时开始\n", t_start);
/**
* 创建执行线程
*/
pthread_create(&tid1,&attr,sort,¶1);
pthread_create(&tid2,&attr,sort,¶2);
/**
* 等待线程结束
*/
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
merge(); //整合
//输出结果来验证
//printElenm(res);
int t_end=clock();//结束时刻
printf("多线程排序%d 时结束\n", t_end);
printf("多线程排序耗时:%d\n", t_end-t_start); //计算程序运行消耗的时间
/**
* 接下来尝试单线程排序
*/
initElem(); //首先还是初始化数组
t_start=clock(); //开始时间
printf("普通排序%d 时开始\n", t_start);
sort(¶3);
t_end=clock();//结束时刻
printf("普通排序%d 时结束\n", t_end);
printf("普通排序耗时:%d\n", t_end-t_start); //计算程序运行消耗的时间
}
void initElem(){
srand((unsigned)time(NULL));
int i;
for(i=0;i<LENGTH;i++){
elem[i]=rand()%MAX+1;
}
}
/**
* [sort description]
* 一个简单的冒泡排序算法
* @param para [description]
*/
void *sort(void * p){
Para * para=(Para*)p;
int i,j,temp;
for(i=para->start;i<para->end;i++){
for(j=para->end;j>i;j--){
if(elem[j]<elem[j-1]){
temp=elem[j];
elem[j]=elem[j-1];
elem[j-1]=temp;
}
}
}
if(para->end-para->start<LENGTH-1){ //如果是部分排序就认为是执行了多线程需要退出,否则不退出
pthread_exit(0);
}
}
void printElenm(int num[LENGTH]){
int i;
for(i=0;i<LENGTH;i++){
printf("%d\n", num[i]);
}
}
void merge(){
int i=0,j=LENGTH/2+1,k=0;
while(i<LENGTH/2+1&&j<LENGTH){
if(elem[i]<elem[j]){
res[k]=elem[i];
k++;
i++;
}else{
res[k]=elem[j];
k++;
j++;
}
}
if(i<LENGTH/2){
for(;i<LENGTH/2+1;i++,k++){
res[k]=elem[i];
}
}else{
for(;j<LENGTH;j++,k++){
res[k]=elem[j];
}
}
}
来源:CSDN
作者:ty1252
链接:https://blog.csdn.net/ty1252/article/details/70833441