学习笔记 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查询



苏格拉底提问

  • 线程问题


  • 并行和并发性的理解







posted @ 2023-10-29 10:03  20211301郑润芃  阅读(2)  评论(0编辑  收藏  举报