学习笔记 7
学习笔记7 20211301
教材知识点总结
4.1 并行计算导论
- 顺序算法与并行算法
- 并行性与并发性:并行中所有任务都同时执行(多处理器),并发(单CPU)
4.2 线程
-
原理:进程是独立的执行单元,线程是某进程同一地址空间上的独立执行单元
-
优点:
- 创建和切换速度更快
- 线程响应速度更快
- 线程更适合并行计算
-
缺点:
- 需要用户明确同步
- 库函数对线程不安全
- 单CPU系统,速度慢
4.3 线程操作
-
执行轨迹和进程类似
-
可在内核模式或用户模式下执行
-
用户模式:在进程的相同地址空间中执行,有自己的执行堆栈
-
优先统一进程中的进程
4.4 线程管理函数
- Pthread库提供了用于线程管理的以下API
- 创建线程:
-
线程ID:不透明的数据类型
-
线程终止:函数结束,终止,或者线程可以调用
-
线程连接:可以等待另一个的终止
4.5 线程示例程序
- 线程计算矩阵的和:利用线程的并发性计算
-线程快速排序:主线调用函数实现快速排序,线程选择基准元素,将数组分为两部分,左边都小于基准,右边都大于,创建两个子线程
4.6 线程同步
-
互斥量:有锁才进行,锁称为互斥量,互相排斥,用之前初始化
-
死锁预防:互斥量使用封锁协议,交叉加锁导致死锁,不存在于并发进程中
-
死锁解决:死锁预防(同一方向)
-
条件变量:互斥量仅用于确保线程只能互斥地访问临界区中的共享数据对象,条件变量提供一种线程协作的方法,与互斥量一起使用
-
生产者-消费者问题:有限缓冲问题,将进程定义为执行实体
-
有限缓冲问题是指在计算机科学中,当数据的输入和输出速率不匹配时,会导致数据在缓冲区中积聚而无法及时处理的情况。简单来说,有限缓冲问题发生在一个固定大小的缓冲区(有限的内存空间)中,当输入数据流的速率超过了处理数据流的速率时,缓冲区会填满,而后续的输入数据将无法存入缓冲区,从而导致数据丢失或处理延迟增加。
-
信号量:进程同步的一种机制,是一种数据结构,使用前必须使用一个初始值和一个空等待队列进行初始化
-
屏障:机制,初始化,在屏障中等待指定数量的线程到达屏障,所有线程开始重新执行,是线程的集合点。
-
高斯消元法:并行化,等待线程加入,简化步骤
-
linux中的线程:不区分线程和进程
- 与其他进程共享某些资源的进程
- 都由clone()系统调用创建的
代码实现
- 用线程的并发计算来计算矩阵的和
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_SIZE 100
int matrix[MAX_SIZE][MAX_SIZE];
int sum = 0;
// 每个线程的计算任务
void* calculateSum(void* arg) {
int start = *(int*)arg;
int n = MAX_SIZE;
int chunk = n / MAX_SIZE;
int localSum = 0;
for (int i = start * chunk; i < (start + 1) * chunk; i++) {
for (int j = 0; j < n; j++) {
localSum += matrix[i][j];
}
}
// 将局部和累加到全局和
pthread_mutex_t mutex;
pthread_mutex_lock(&mutex);
sum += localSum;
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main() {
int n; // 矩阵的大小
pthread_t threads[MAX_SIZE];
void* status;
printf("请输入矩阵的大小:");
scanf("%d", &n);
// 生成随机矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = rand() % 100; // 生成0到99之间的随机数
}
}
// 创建线程并发计算
for (int i = 0; i < MAX_SIZE; i++) {
int* threadId = malloc(sizeof(int));
*threadId = i;
pthread_create(&threads[i], NULL, calculateSum, (void*)threadId);
}
// 等待所有线程计算完成
for (int i = 0; i < MAX_SIZE; i++) {
pthread_join(threads[i], &status);
}
printf("整数矩阵中所有元素的和为:%d\n", sum);
return 0;
}
- 用并发线程和线程连接以及屏障解线性方程组
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_SIZE 100
int matrix[MAX_SIZE][MAX_SIZE];
int sum = 0;
// 每个线程的计算任务
void* calculateSum(void* arg) {
int start = *(int*)arg;
int n = MAX_SIZE;
int chunk = n / MAX_SIZE;
int localSum = 0;
for (int i = start * chunk; i < (start + 1) * chunk; i++) {
for (int j = 0; j < n; j++) {
localSum += matrix[i][j];
}
}
// 将局部和累加到全局和
pthread_mutex_t mutex;
pthread_mutex_lock(&mutex);
sum += localSum;
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main() {
int n; // 矩阵的大小
pthread_t threads[MAX_SIZE];
void* status;
printf("请输入矩阵的大小:");
scanf("%d", &n);
// 生成随机矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = rand() % 100; // 生成0到99之间的随机数
}
}
// 创建线程并发计算
for (int i = 0; i < MAX_SIZE; i++) {
int* threadId = malloc(sizeof(int));
*threadId = i;
pthread_create(&threads[i], NULL, calculateSum, (void*)threadId);
}
// 等待所有线程计算完成
for (int i = 0; i < MAX_SIZE; i++) {
pthread_join(threads[i], &status);
}
printf("整数矩阵中所有元素的和为:%d\n", sum);
return 0;
}
问题与解决方案
- 问题一:不太清楚pthread的使用
- 问题一解决方案:问gpt、在linux中用man查询
苏格拉底提问
-
线程问题
-
并行和并发性的理解