一、实验概述
实现一个数独解决程序,使用多个线程或多个进程,运行在一台机器上。
试着利用你所有的CPU核心,使
你的程序运行得尽可能快!
就是在lab1给的框架下写一个符合要求的程序
然后我这里只完成了基础版本,没有完成高级版本
二、实验过程
在仔细阅读readme文件后,以及浏览相关文件夹之后,发现只需在main.cc文件下编写代码即可,以及改写Makefile文件和solve_sudoku_dancing_links文件
main.cc:
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <pthread.h>
#include "sudoku.h"
#include<stdlib.h>
typedef struct {
int first;
int last;
int** tqa;//问题和结果数组(test question and answer)
}threadtask;
void* threadfun(void* args){ //这个是线程运行函数,每个线程解决一部分数独题目
threadtask* task = (threadtask*) args;
int first=task->first;
int last=task->last;
int** tqa=task->tqa;
int i=0;
for(i=first;i<last;i++){
solve_sudoku_dancing_links(tqa[i]);
}
pthread_exit(NULL);
return NULL;
}
int main(int argc, char* argv[])
{
char testfile[128]= "\0";
while(scanf("%s",testfile)){//接收文件路径输入
char puzzle[128];
FILE* f1 = fopen(testfile, "r");
int testnumber=0;
while (fgets(puzzle, sizeof puzzle, f1) != NULL) {
testnumber++;//统计题目数量
}
fclose(f1);
int threadnumber=8;//线程数
int i=0;
int row = testnumber,col = N;
//申请
int **testqa = (int**)malloc(sizeof(int*) * row); //sizeof(int*),不能少*,一个指针的内存大小,每个元素是一个指针。
for (i = 0;i < row;i++)
{
testqa[i] = (int*)malloc(sizeof(int) * col);//保存结果的数组
}
FILE* fp = fopen(testfile, "r");
i=0;
char tt[testnumber][128];//临时数组
while (fgets(tt[i], sizeof tt[i], fp) != NULL) {
i++;
}
//输入转换
for(int t1=0;t1<testnumber;t1++){
for (int t2 = 0; t2 < N; t2++) {
testqa[t1][t2] = (int)(tt[t1][t2] - '0');
}}
int pertask= testnumber/threadnumber;
threadtask threadgroup[threadnumber];
pthread_t th[threadnumber];
if(pertask>=1){//为每个线程分配任务
for(i=0;i<threadnumber;i++)
{
int first=(int)pertask*i;//开始平均分配任务
int last;
if(i!=threadnumber-1)
last=(int)pertask*(i+1);
else
last=testnumber;
threadgroup[i].first=first;
threadgroup[i].last=last;
threadgroup[i].tqa=testqa;
if(pthread_create(&th[i], NULL, threadfun, &threadgroup[i])!=0)
{//创建线程
perror("pthread_create failed");
exit(1);
}
}
for(i=0;i<threadnumber;i++)
pthread_join(th[i], NULL);
}
else{//一个线程情况
threadgroup[0].first=0;
threadgroup[0].last=testnumber;
threadgroup[0].tqa=testqa;
if(pthread_create(&th[0], NULL, threadfun, &threadgroup[0])!=0)
{
perror("pthread_create failed");
exit(1);
}
pthread_join(th[0], NULL);
}
int j=0;
int k=0;
//输出结果
for(j=0;j<testnumber;j++){
for(k=0;k<N;k++){
printf("%d",testqa[j][k]);
}
printf("\n");
}
free(testqa);
fflush(stdout);
}
return 0;
}
大概思路是每接收一个文件路径输入(以字符串形式),就fopen它,然后提取里面的内容,统计数独题目的个数,平均分配给多个线程(我这里设置8个线程),每个线程要接收分配到的任务,调用solve_sudoku_dancing_links函数来解题,这里solve_sudoku_dancing_links函数我是改过参数的,传一个数组指针,数独解题结果就在返回这个指针里。最后输出即可。
然后是Makefile文件:
CXXFLAGS+=-O2 -ggdb -DDEBUG
CXXFLAGS+=-Wall -Wextra
all: sudoku_solve
sudoku_solve: main.cc sudoku_dancing_links.cc
g++ -O2 -o $@ $^ -lpthread
sudoku_dancing_links.cc改动:
只有一点点改动:
1.
Dance(int* inout) : inout_(inout), cur_node_(0)
代码93行:
Dance()把inout[81]改成* inout,即改成指针
2.
文件结尾处:
solve_sudoku_dancing_links改动
bool solve_sudoku_dancing_links(int* qa)
{
Dance d(qa);
return d.solve();
}
三、实验结果
四、实验总结
理解实验框架不容易(对我来说)。弄明白整这个实验逻辑就行,就是先理解输入输出,然后调用实验给的算法解数独,最后规范输出,编写Makefile文件即可。