diff --git a/Lab1/README.md b/Lab1/README.md
index fefce8415e7803535a751f204d3b239044d31b01..bea0777adc160411a7f8b4b0b17c403f3d0bfb19 100644
--- a/Lab1/README.md
+++ b/Lab1/README.md
@@ -1,193 +1,239 @@
-# Lab 1: “Super-fast” Sudoku Solving
+Lab 1: “Super-fast” Sudoku Solving
+Enter in the folder you have cloned from our lab git repo, and pull the latest commit.
-Enter in the folder you have cloned from our lab git repo, and pull the latest commit.
+git pull
-`git pull`
+You can find this lab1's instruction in Lab1/README.md
-You can find this lab1's instruction in `Lab1/README.md`
+All materials of lab1 are in folder Lab1/
-All materials of lab1 are in folder `Lab1/`
+1. Overview
+Implement a Sudoku solving program, using multiple threads or multiple processes, running on a single machine. Try to utilize all your CPU cores and make your program run as fast as possible!
-## 1. Overview
+实现一个数独解决程序,使用多个线程或多个进程,运行在一台机器上。 试着利用你所有的CPU核心,让你的程序尽可能快地运行!
-Implement a Sudoku solving program, using multiple threads or multiple processes, running on a single machine. Try to **utilize all your CPU cores** and make your program **run as fast as possible**!
+Goals
+Practice basic parallel programming skills, such as using multiple threads/processes;
+练习基础的并行编程技能,例如使用多线程/进程
+Get familiar with Unix OS environment development (eg., file I/O, get timestamp);
+熟悉Unix操作系统环境开发(例如: 文件I/O,获取时间戳)
+Get familiar with source code version control tools (git), and learn to collaborate with others using github;
+熟悉源代码版本控制工具(git),学习使用github与他人协作
+2. Background
+2.1 Introduction to Sudoku
+Sudoku (originally called Number Place) is a logic-based combinatorial number-placement puzzle.
-### Goals
+数独(Sudoku,原名Number Place)是一种基于逻辑的组合数字放置谜题。
-* Practice basic parallel programming skills, such as using multiple threads/processes;
-* Get familiar with Unix OS environment development (eg., file I/O, get timestamp);
-* Get familiar with source code version control tools (git), and learn to collaborate with others using github;
+You are given a 9×9 board of 81 squares logically separated into 9 columsn, 9 rows, and 9 3×3 subsquares. The goal is, given a board with some initial numbers filled in (we call it a Sudoku puzzle), fill in the rest of the board so that every column, row, and subsquare have all the digits from 1 to 9 and each digit appears only once (we call it a Sudoku solution).
-## 2. Background
+给你一个9×9的板子,上面有81个正方形,逻辑上分成9列、9行和9个3×3子正方形。 我们的目标是,给定一个板子和一些初始数据填写(我们称之为一个数独题 ),使用1到9的数字来填写的板子中的每一列,每一行,每一个子正方形,并且每个数字只出现一次(我们称之为数独解)。
-### 2.1 Introduction to Sudoku
+An example Sudoku puzzle:
-Sudoku (originally called Number Place) is a logic-based combinatorial number-placement puzzle.
+Sudoku
-You are given a 9×9 board of 81 squares logically separated into 9 columsn, 9 rows, and 9 3×3 subsquares. The goal is, given a board with some initial numbers filled in (we call it a **Sudoku puzzle**), fill in the rest of the board so that every column, row, and subsquare have all the digits from 1 to 9 and each digit appears only once (we call it a **Sudoku solution**).
+An example Sudoku solution to above puzzle:
+Sudoku
- An example Sudoku puzzle:
+2.2 Some useful resources
+If you have no idea about what algorithms can be used to solve Sudoku puzzles, we suggest you read this. To simplify your work, we have provided a simple implementation (Lab1/src/Sudoku) of 4 Sudoku solving algorithms (some are slow, some are fast), but without using multiple threads/processes. The two files test1 and test1000 contain many puzzles for you to test.
-
+如果你不知道什么算法可以用来解决数独谜题,我们建议你阅读这个。
- An example Sudoku solution to above puzzle:
-
-
-
-### 2.2 Some useful resources
-
-If you have no idea about what algorithms can be used to solve Sudoku puzzles, we suggest you read [this](https://rafal.io/posts/solving-sudoku-with-dancing-links.html). To simplify your work, we have provided a simple [implementation](src/Sudoku/) `(Lab1/src/Sudoku`) of 4 Sudoku solving algorithms (some are slow, some are fast), but without using multiple threads/processes. The two files *test1* and *test1000* contain many puzzles for you to test.
+为了简化您的工作,我们提供了一个简单的实现 (Lab1/src/Sudoku )中的4个Sudoku求解算法(有些慢,有些快),但不使用多线程/进程。 两个文件test1和test1000包含许多要测试的谜题。
Of course, you are always encouraged (not mandatory) to implement those algorithms by yourselves and even your own algorithms (if you have time).
-## 3. Your Lab Task
-
-### 3.1 Write a program
+当然,我们总是鼓励(不是强制性的)您自己实现这些算法,甚至是您自己的算法(如果您有时间的话)。
+3. Your Lab Task
+3.1 Write a program
Implement a program which satisfies the following requirements:
-#### 3.1.1 Program input and output
+实施满足下列要求的计划:
-##### **Input**
+3.1.1 Program input and output
+3.1.1.1 Input
+Your program must have no arguments during start. Attention, your program must be called sudoku_solve, just typing ./sudoku_solve and your program will run correctly.
-1. When executing the compiled program from the code you submit, it must **not** take any parameters and the program must be named ***sudoku_solve***. In other words, your program can be run normally by typing `./sudoku_solve` in the terminal.
-2. But after start, your program needs to be able to read multiple strings from ***stdin***, which are separated by line breaks. The content of these strings are **the paths of the Sudoku puzzles files**.
-3. In each input file, **each line** of the file represents a Sudoku puzzle that needs to be solved. Each line contains 81 digits, where the first 9 digits represent the first row of the Sudoku puzzle, the 10th to the 18th digits represent the second row of the puzzle, and so on. The digit 0 represents a blank that needs to be filled in when solving the puzzle.
+你的程序**必须在启动时**没有参数。 注意,你的程序必须被称为sudoku_solve,只需要输入./sudoku_solve ,您的程序将正确运行。
-**3.1.1.1 Puzzle file example**
+But after start, your program should be able to read multiple strings from stdin, where each string is separated by a line-break. Each string is a name of a file, which contains one or more Sudoku puzzles that your program is going to solve.
-In the following image, we have printed three Sudoku puzzle **files** in the terminal. They contain one, two, and three puzzles, and their names are test1, test2, and test3.
+但是在开始之后,你的程序应该能够从stdin中读取多个字符串,其中每个字符串由一个换行符分隔。 每个字符串是一个文件的名,它包含一个或多个你的程序将解决的数独谜题。
-
+In the input file, each line is a Sudoku puzzle that needs to be solved. Each line contains 81 decimal digits. The 1st-9th digits are the 1st row of the 9×9 grid, and the 10th-18th digits are the 2nd row of the 9×9 grid, and so on. Digit 0 means this digit is unknown and your program needs to figure it out according to the Sudoku rules described above.
-**3.1.1.2 Example input from terminal**
+在输入文件中,每一行是一个需要解决的数独谜题。 每行包含81位十进制数字。 第1 ~ 9位是9×9网格的第一行,第10 ~ 18位是9×9网格的第2行,以此类推。 数字0表示这个数字是未知的,你的程序需要根据上面描述的数独规则来计算它。
-In the following code snippet, we showed how to input Sudoku puzzle files that need to be solved from the terminal after your program starts running:
+Example contents
+
+Input file
+
+Example input
-```
./test1
./test2
./test3
-```
-
-##### Output
+3.1.1.2 Output
+For each test case, you just only output the Sudoku solutions. And don't forget, the output order should correspond with the input order of Sudoku puzzles.
-For each Sudoku puzzle in file, your program should only output the solution to the puzzle to ***stdout***. The format of the solution should be the same as the puzzle, except that all 0s in the puzzle should be replaced with the correct numbers. Also, remember that the order of the answers should be consistent with the order of the input Sudoku puzzles.
+对于每个测试用例,您只输出Sudoku解决方案。 不要忘记,输出顺序应该与数独谜题的输入顺序相对应。
-**3.1.1.3 Example output**
+Example output
-```
312647985786953241945128367854379126273461859691285473437592618569814732128736594
693784512487512936125963874932651487568247391741398625319475268856129743274836159
869725413512934687374168529798246135231857946456319872683571294925483761147692358
693784512487512936125963874932651487568247391741398625319475268856129743274836159
364978512152436978879125634738651429691247385245389167923764851486512793517893246
378694512564218397291753684643125978712869453859437261435971826186542739927386145
-```
+Output order requirement
+
+In the example of input above, the order of filename entered is ./test1, ./test2 and ./test3. So, you should output the solutions of Sudoku puzzles in file test1 firstly, then file test2 and finally file test3. Needless to say, the solutions should be outputed in the same sequence as the puzzles are inputted in.
+
+在上面输入的例子中,文件名的输入顺序是./test1 , ./test2和./test3。 因此,您应该首先在文件test1中输出数独谜题的解决方案,然后文件test2,最后文件test3。 不用说,答案应该以输入谜题的相同顺序输出。
+
+In the example of output above, the 1st line is the solution of Sudoku puzzle in file test1. After that, the 2nd line and 3rd line are the solutions of 1st and 2nd Sudoku puzzles in file test2. Finally, the 4th line, 5th line and 6th line are the solutions of 1st, 2nd and 3rd Sudoku puzzles in file test3.
+
+在上面的输出示例中,第一行是test1文件中的数独谜题的解决方案。 然后,第二行和第三行是文件test2中第1和第2个数独谜题的答案。 最后,第4行、第5行和第6行是test3文件中第1、2和3个数独谜题的答案。
+
+3.1.3 Implementation requirements
+3.1.3.1 Basic version
+Your program should be able to:
+
+Accept one input file name, and the size of the input file is smaller than 100MB.
+Successfully solve the puzzles in the input file, and output the results in the format described before.
+Use multiple threads/processes to make use of most of your machine's CPU cores.
+[Tips]: 1) Use event queue to dispatch tasks and merge results to/from worker threads. 2) Dynamically detect how many CPU cores are there on your machine, in order to decide how many threads/processes your program uses. 3) Be careful about the contention among multiple threads/processes
+
+你的程序应该能够:
-**3.1.1.4 Output order requirement**
+接受一个输入文件名,输入文件大小小于100MB。
-Taking the three test files above as an example, your program needs to output the result of `./test1` first, then `./test2`, and finally `./test3`. Additionally, the order of answers corresponding to each file should be consistent with the order of puzzles in the file.
+成功解决输入文件中的谜题,并以前面描述的格式输出结果。
-In the example output, the 1st line corresponds to the solution of the Sudoku puzzle in `./test1`. The 2nd and 3rd lines correspond to the 1st and 2nd puzzles in `./test2`. The 4th, 5th, and 6th lines correspond to the 1st, 2nd, and 3rd puzzles in test3.
+使用多线程/进程可以充分利用机器的大部分CPU核心。
-#### 3.1.2 Implementation requirements
+[提示]:1)使用事件队列来调度任务,并将结果合并到工作线程中。 2)动态检测有多少CPU核在你的机器上,以决定有多少线程/进程,你的程序使用。 3)小心多线程/进程之间的争用
-##### 3.1.2.1 Basic version
+3.1.3.2 Advanced version
+Your program should be able to:
-Your program should be able to:
+Complete all the requirements in the basic version.
+Accept any number of input file names, and the size of input file can be any large (as long as it can be stored on your disk)
+When the program is solving puzzles in the previously input file(s), the program can meanwhile accept more input file names from stdin.
+[Tips]: 1) Use a dedicated thread to accept input; 2) To avoid consuming all the memory, read different parts of the file into memory and solve them one by one; 3) You are encouraged to try more optimizations such as cache coherency processing.
-1. Accept **one** input file name, and the size of the input file is smaller than 100MB.
-2. Successfully solve the puzzles in the input file, and output the results in the format described before.
-3. Use multiple threads/processes to make use of most of your machine's CPU cores.
+你的程序应该能够:
-\[Tips\]:
+完成基本版本中的所有要求。
-1. Use an event queue to dispatch tasks and merge results to/from worker threads.
-2. Dynamically detect how many CPU cores your machine has to determine how many threads/processes your program should use.
-3. Be careful about contention between multiple threads/processes.
+接受任意数量的输入文件名,输入文件的大小可以任意大(只要它可以存储在您的磁盘上)
-##### 3.1.2.2 Advanced version
+当程序在解决之前输入文件中的谜题时,程序可以同时从stdin接受更多的输入文件名。
-Your program should be able to:
+[提示]:1)使用专用线程接受输入; 2)为避免占用全部内存,请将文件的不同部分读入内存,并逐个解决; 3)鼓励你尝试更多的优化,如缓存一致性处理。
-1. Complete all the requirements in the basic version.
-2. Accept **any number of** input file names, and the size of input file can be **any large** (as long as it can be stored on your disk)
-3. When the program is solving puzzles in the previously input file(s), the program can **meanwhile accept more input file names from *stdin***.
+3.2. Test script
+You can test your program using the script (Lab1.sh) that comes with this Lab.
-\[Tips\]:
+您可以使用本Lab附带的脚本(Lab1.sh)测试您的程序。
-1. Use a dedicated thread to accept input.
-2. To avoid exhausting all memory, read different parts of the file into memory and solve them one by one.
-3. You are encouraged to try more optimizations, such as cache coherency processing.
+3.2.1 Notes
+You can use the script on most Linux environments
-### 3.2. Test script
+您可以在大多数Linux环境中使用该脚本
-We have provided a script for you to use so that you can test your program before submitting, you can use this shell script on most Linux systems.
+Requires support for the screen command
-It will verify the correctness of the program based on the output, and show you the time your program takes.
+需要支持的screen命令
-##### 3.2.1 Get prepared
+ You can use "which screen" to see if the screen command is already installed, if not you can refer to the following command download:
-1. This script requires you to provide **two input files**. These two files need to be placed in the **same directory as the script**. The following describes how to prepare these two input files:
+你可以使用“which screen”来查看screen命令是否已经安装,如果没有,你可以参考以下命令下载:
- a. The content of the **first file** is a list of Sudoku puzzle files which will be input to your program. For example, we name the first file as `test_group`, and we prepared 2 puzzle files(see in 3.1.1.1) to test our program, the first file is named as "test1" and it has 1 puzzle to be solved, and the other file is named "test1000" and it has 1000 puzzles to be solved. Then the content format of `test_group` is as follows:
+ ubuntu: apt-get install screen
-
+ centos: yum install screen
+The executable file can only be named sudoku_solve
- b. The content of the **second file** is a list of Sudoku solution files to the puzzles you prepared. Take the example of the first file above, we name the second file as `answer_group`. Same to the `test_group` above, `answer_group` should also contain 2 answer files, the first answer file corresponds to ""test1"" in `test_group`, it's named "answer1" and it has 1 solution, the second answer file corresponds to "test1000" in `test_group`, it's name is "answer1000" and it has 1000 solutions. Then the content format of `answer_group` is as follows:
+可执行文件的名称只能为sudoku_solve
-
+sudoku_solve executable file, Lab1.sh script should be placed in the same directory
- You can create your own test files and put them in the test group and answer group if you want.
+sudoku_solve可执行文件,Lab1.sh脚本应放在同一目录下
-2. Using this script requires installing the `screen` command. You can use the `which screen` command to check if `screen` is installed on your local machine. If it is not installed, you can install it using the following command:
-```shell
- ubuntu(debian): sudo apt-get install screen #This or apt
- sudo apt install screen #This or apt-get
- centos(redhat): yum install screen 2.
-```
-3. The compiled executable file should be named **sudoku_solve**, and it need to be placed in the **same directory as this script**.
+If your file system is not in ext4 format, the performance test may not succeed and only the basic test can be performed.
-4. If your file system is not in the **ext4** format, this script may not be able to do performance tests successfully and can only do basic tests. You can use the following command to check which paths are mounted on an exf4-formatted disk:
+如果文件系统不是ext4格式,可能会导致性能测试失败,只能执行基本测试。
- ```shell
- df -h --type=ext4
- ```
+ You can see which path mounted ext4 disks in the following way:
-
+您可以通过以下方式查看ext4磁盘挂载的路径:
-5. The script will generate a sub-folder contains two files named Basic(Advanced)_Result and Basic(Advanced)_Answer, the Result file contains your program's output and the Answer file contains reference output. The script will delete these two folders every time it runs, so if you need the data, make sure to copy them before running the script.
+ df -h --type=ext4
+Sudoku
+The script will generate a subfolder with Basic(Advanced)_Result and Basic(Advanced)_Answer, Result is your output and Answer is the reference output. At each run, the script will delete the two files , so if you need this data, please copy it first before running the script.
-6. The script presents the time spent as relative, and there is a relatively fixed processing time for each run. For example, if your program takes 1300ms to solve a Sudoku problem, but the script takes 800ms for preparation, the final display will show 2100 milliseconds. Additionally, everyone's configuration and performance are different, resulting in different times. This means that you only need to keep optimizing on your own machine instead of comparing with others. Rest assured that the same environment will be used for the final scoring.
+脚本将生成一个基本(高级)\结果和基本(高级)_Answer的子文件夹,结果是你的输出,答案是参考输出。 每次运行时,脚本都会删除这两个文件,所以如果您需要这些数据,请在运行脚本之前先复制它们。
-7. (**Very important**) If you want to get a high score (script test), it is better to flush the data in the buffer in time.
+The time taken for script presentation is relative, each time there will be a relatively fixed processing time. For example, your program used 1300ms to solve the sudoku problem, but the script preparation took 800ms. eventually, the script will show 2100ms. Also everyone's configuration and performance is different, resulting in different times, which means you only need to keep optimizing on your machine, not comparing it with others. Please be assured that the same environment will be used for the final scoring.
-##### 3.2.2 Script Usage
+脚本呈现所花费的时间是相对的,每次都会有一个相对固定的处理时间。 例如,您的程序使用1300ms来解决数独问题,但是脚本准备需要800ms。 最终,脚本将显示2100ms。 此外,每个人的配置和性能都是不同的,导致不同的时间,这意味着您只需要在您的机器上进行优化,而不需要与其他机器进行比较。 请放心,最终评分将使用相同的环境。
-```shell
+(Very important) If you want to get a high score (script test), it is better to flush the data in the buffer in time.
+
+(非常重要)如果你想要得到一个高分(脚本测试),它是最好的刷新数据在缓冲区的时间。
+
+3.2.2 Script Usage
sudo ./Lab1.sh test_group answer_group
-```
+Parameter explanation:
+
+ The script takes two parameters
+
+ Para1(For example: test_group ) : A file that create by yourself. This file is placed in the path of the different test files. For example, if the test file group contains: . /test1 . /test1000 two input test files, the structure is as follows:
+
+ Para1(例如:test_group):由自己创建的文件。 该文件被放置在不同测试文件的路径中。 例如,测试文件组包含: ./ test1 ./test1000两个输入测试文件,结构如下:
+
+Sudoku
+
+ Para2(For example: answer_group) : A file like parameter 1 but with the path to the answer to the test file. For example, if the test file group contains: . /test1 . /test1000 two input test files, the answer file group contains: . /answer1 . /answer1000 , and the structure is as follows:
-The script takes two parameters, they are the 2 prepared files in 3.2.1.
+ Para2(例如:answer_group):一个类似于参数1的文件,但带有测试文件的答案的路径。 例如,测试文件组包含: ./ test1 ./test1000两个输入的测试文件,回答文件组包含: ./ answer1 ./answer1000,结构如下:
-Note that this output below means that you are missing a line break at the end of your answer group, which will not be recognized. Of course, the path of your puzzle file should be in the same order as the answer path.
+Sudoku
-
+You can create your own test files and put in the combinations you want.
+
+Note that this output below means that you are missing a line break at the end of your test file, which will not be recognized. Of course, the path of your answer file should be in the same order as the test path.
+
+您可以创建自己的测试文件,并放入您想要的组合。
+
+请注意,下面的输出意味着您在测试文件的末尾丢失了一个换行符,它将无法被识别。 当然,回答文件的路径应该与测试路径的顺序相同。
+
+Sudoku
An example:
-
+Sudoku
+
+4. Lab submission
+Please put all your code in folder Lab1 and write a Makefile so that we can compile your code in one single command make. The compiled runnable executable binary should be named sudoku_solve and located in folder Lab1. If you do not know how to write Makefile, you can find a simple example in Lab1/src/Sudoku. Please carefully following above rules so that TAs can automatically test your code!!!
+
+Please submit your lab program and performance test report following the guidance in the Overall Lab Instructions (../README.md)
-## 4. Lab submission
+请把你所有的代码放在Lab1文件夹中,然后写一个Makefile,这样我们就可以在一个命令make中编译你的代码。 编译后的可执行二进制文件应该命名为sudoku_solve,并位于Lab1文件夹中。 如果你不知道如何编写Makefile,你可以在Lab1/src/Sudoku中找到一个简单的例子。 请仔细遵守以上规则,以便助教能够自动测试你的代码!!
-Please put all your code in folder `Lab1` and write a `Makefile` so that we **can compile your code in one single command** `make`. The compiled runnable executable binary should be named `sudoku_solve` and located in folder `Lab1`. If you do not know how to write `Makefile`, you can find a simple example in `Lab1/src/Sudoku`. Please carefully following above rules so that TAs can automatically test your code!!!
+请按照实验总体说明 (../README.md)中的指导提交你们的实验计划和性能测试报告。
-Please submit your lab program and performance test report following the guidance in the [Overall Lab Instructions](../README.md) (`../README.md`)
+5. Grading standards
+You can get 38 points if you can: 1) finish all the requirements of the basic version, and 2) your performance test report has finished the two requirements described before. If you missed some parts, you will get part of the points depending how much you finished
-## 5. Grading standards
+如果可以,你可以得38分: 1)完成了基础版的所有要求,2)性能测试报告完成了之前描述的两个要求。 如果你错过了一些部分,你将得到部分的分数取决于你完成了多少
-1. You can get 38 points if you can: 1) finish all the requirements of the basic version, and 2) your performance test report has finished the two requirements described before. If you missed some parts, you will get part of the points depending how much you finished
-2. You can get 40 points (full score) if you can: 1) finish all the requirements of the advanced version, and 2) your performance test report has finished the two requirements described before. If you missed some parts, you will get part of the points depending how much you finished.
+You can get 40 points (full score) if you can: 1) finish all the requirements of the advanced version, and 2) your performance test report has finished the two requirements described before. If you missed some parts, you will get part of the points depending how much you finished.
+如果可以,你可以得40分: 1)完成高级版本的所有要求,2)您的性能测试报告已完成前面描述的两个要求。 如果你错过了一些部分,你将得到部分的分数取决于你完成了多少。
diff --git a/Lab1/src/Sudoku/dancing_link/src/Makefile b/Lab1/src/Sudoku/dancing_link/src/Makefile
new file mode 100755
index 0000000000000000000000000000000000000000..d7a4ff4623ee016b5ea2877e438654068ad2988d
--- /dev/null
+++ b/Lab1/src/Sudoku/dancing_link/src/Makefile
@@ -0,0 +1,7 @@
+CXXFLAGS+=-O2 -ggdb -DDEBUG
+CXXFLAGS+=-Wall -Wextra
+
+all: sudoku_solve
+
+sudoku_solve: main_multi.cc sudoku_dancing_links.cc
+ g++ -O2 -o $@ $^
diff --git a/Lab1/src/Sudoku/dancing_link/src/main_multi.cc b/Lab1/src/Sudoku/dancing_link/src/main_multi.cc
new file mode 100755
index 0000000000000000000000000000000000000000..82b0f65cd0d272b7cfaab69c96733ecc563470a0
--- /dev/null
+++ b/Lab1/src/Sudoku/dancing_link/src/main_multi.cc
@@ -0,0 +1,179 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "sudoku_dancing_multi.h"
+using namespace std;
+
+vector> puzzle_array; //所有线程共用的一个数组,存储从文件中读到的数独题目
+pthread_mutex_t array_mutex = PTHREAD_MUTEX_INITIALIZER; //访问puzzle_array和current_index的锁
+pthread_cond_t work_available_cond = PTHREAD_COND_INITIALIZER;
+int current_index =0; //标记当前puzzle_array中数组题目取到第几个了
+
+queue filenameRead_queue; //存储文件名
+pthread_mutex_t filenameRead_mutex = PTHREAD_MUTEX_INITIALIZER; //访问filenameRead_queue的锁
+
+pthread_cond_t output_cond = PTHREAD_COND_INITIALIZER;
+int head_index =0;
+
+int64_t now()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec * 1000000 + tv.tv_usec;
+}
+
+//输入文件名
+void* filenameRead_thread(void* arg){
+ string filename;
+ while(true){
+ cin>>filename;
+ pthread_mutex_lock(&filenameRead_mutex);
+ // printf("输入");
+ filenameRead_queue.push(filename);
+ pthread_mutex_unlock(&filenameRead_mutex);
+ }
+ return nullptr;
+}
+
+//读取文件:1.读取文件名;2.写入数独数组
+void* read_file_thread(void* arg){
+ while(true){
+ string filename;
+ pthread_mutex_lock(&filenameRead_mutex);
+ if(!filenameRead_queue.empty()){
+ filename = filenameRead_queue.front();
+ filenameRead_queue.pop();
+ // printf("读取文件名");
+ }
+ pthread_mutex_unlock(&filenameRead_mutex);
+
+ if(!filename.empty()){
+ FILE* fp = fopen(filename.c_str(), "r");
+ if(fp !=NULL){
+ // printf("读取文件");
+ char puzzle[128];
+ while (fgets(puzzle, sizeof(puzzle), fp) != NULL) { //读一行,一行为一道数独题目
+ if (strlen(puzzle) >= N) {
+ pthread_mutex_lock(&array_mutex);
+ puzzle_array.emplace_back(string(puzzle), false); //数独题读到全局共享数组中
+ pthread_cond_signal(&work_available_cond);
+ pthread_mutex_unlock(&array_mutex);
+ }
+ }
+ fclose(fp);
+ }
+ }
+ }
+ return nullptr;
+}
+
+//调用具体解数独方法的线程函数:1.修改数组;2.唤醒输出线程; 3.被唤醒
+void* solve_puzzles(void* arg){
+ bool (*solve)(int*) = reinterpret_cast(arg);
+ while(true){
+ vector> local_puzzles;
+ int start_index;
+ pthread_mutex_lock(&array_mutex);
+ while(current_index >= puzzle_array.size()){
+ pthread_cond_wait(&work_available_cond, &array_mutex);
+ }
+ // printf("读取数独");
+ start_index = current_index;
+ for(int i = 0; i < 10 && current_index < puzzle_array.size(); ++i){
+ local_puzzles.push_back(puzzle_array[current_index]);
+ ++current_index;
+ }
+ pthread_mutex_unlock(&array_mutex);
+ if(local_puzzles.empty()){
+ break;
+ }
+
+ int board[N];
+ for(int i = 0; i < local_puzzles.size(); ++i){
+ // printf("解数独");
+ string& puzzle = local_puzzles[i].first;
+ if(puzzle.length() >= N){
+ for (int i = 0; i < N; ++i) {
+ board[i] = puzzle[i] - '0'; // 字符 '0' ~ '9' 转换成整数 0 ~ 9
+ }
+ if(solve(board)){
+ string result;
+ for(int j = 0; j < N; ++j){
+ result += to_string(board[j]);
+ }
+ local_puzzles[i]=make_pair(result,true);
+ }else{
+ printf("No:%s\n",puzzle.c_str());
+ }
+
+ }
+ pthread_mutex_lock(&array_mutex);
+ for(int i=0;i threads(num_cores);
+ pthread_create(&filenameRead_tid, nullptr, filenameRead_thread, nullptr); //处理读文件名的线程
+ pthread_create(&read_tid, nullptr, read_file_thread, nullptr); //通过文件名打开文件,读到数独题目
+ pthread_create(&output_tid, nullptr, output_thread, nullptr);
+ for(int i = 0; i < num_cores; ++i){
+ pthread_create(&threads[i], nullptr, solve_puzzles, reinterpret_cast(solve_sudoku_dancing_links));
+ }
+
+ for(int i = 0; i < num_cores; ++i){
+ pthread_join(threads[i], nullptr);
+ }
+ pthread_join(filenameRead_tid, nullptr);
+ pthread_join(read_tid, nullptr);
+ pthread_join(output_tid, nullptr);
+
+ return 0;
+}
+
diff --git a/Lab1/src/Sudoku/dancing_link/src/sudoku_dancing_links.cc b/Lab1/src/Sudoku/dancing_link/src/sudoku_dancing_links.cc
new file mode 100755
index 0000000000000000000000000000000000000000..17e9bac68a46ce48046090a5a4f64b60ae2160f0
--- /dev/null
+++ b/Lab1/src/Sudoku/dancing_link/src/sudoku_dancing_links.cc
@@ -0,0 +1,259 @@
+#include
+#include
+#include