首页 > 其他分享 > 《信息安全系统设计与实现》学习笔记7

《信息安全系统设计与实现》学习笔记7

时间:2023-10-28 23:15:09浏览次数:46  
标签:right int void 信息安全 笔记 学习 线程 pthread left

第四章 并发编程

并行计算

要求解某个问题,先要设计一种算法,描述如何一步步地解决问题,然后用计算机程序以串行指令流的形式实现该算法。在只有一个 CPU的情况下,每次只能按顺序执行某算法的一个指令和步骤。但是,基于分治原则(如二又树查找和快速排序等)的算法经常表现出高度的并行性,可通过使用并行或并发执行来提高计算速度。并行计算是一种计算方案,它尝试使用多个执行并行算法的处理器更快速地解决问题。

  • 顺序算法与并行算法

    begin-end代码块中的顺序算法可能包含多个步骤。

  • 并行性与并发性

    • 在理想情况下,并行算法中的所有任务都应该同时实时执行。
    • 真正的并行执行只能在有多个处理组件的系统中实现,比如多处理器或多核系统。
    • 在单CPU系统中,一次只能执行一个任务。在这种情况下,不同的任务只能并发执行,即在逻辑上并行执行。

线程

  • 线程的原理

    • 线程是某进程同一地址空间上的独立执行单元。创建某个进程就是在一个唯一地址空间创建一个主线程。当某进程开始时,就会执行该进程的主线程。
  • 线程的优点

    • 线程创建和切换速度更快

    • 线程的响应速度更快

    • 线程更适合并行运算

  • 线程的缺点

    • 由于地址空间共享,线程需要来自用户的明确同步。

    • 许多库函数可能对线程不安全。通常,任何使用全局变量或依赖于静态内存内容的函数,线程都不安全。

    • 在单CPU系统上,使用线程解决问题实际上要比使用顺序程序慢。

线程操作

  • 线程的执行轨迹与进程类似。线程可在内核模式或用户模式下执行。在用户模式下,线程在进程的相同地址空间中执行,但每个线程都有自己的执行堆栈。

线程管理函数

  • 创建线程

    • 使用pthread_create()

      int pthread_create(pthread_t *pthread_id,pthread_attr_t *attr,void *(*func)(void*),void *arg)
      
    • attr 参数的使用步骤。
      (1)定义一个pthread属性变量pthread attr tattr。
      (2)用pthread attrinit (&attr)初始化属性变量。
      (3)设置属性变量并在pthread create0)调用中使用。
      (4)必要时,通过pthread attr destroy (&attr)释放attr 资源。

  • 线程ID

    int pthread_equal(pthread_t t1,pthread_t t2);
    

    如果是不同的线程,返回0,否则返回非0

  • 线程终止

    int pthread_exit(void *status);
    

    进行显式终止,其中状态是线程的退出状态。

  • 线程连接

    int pthread_join(pthread_t thread,void **status_ptr)
    

    终止线程的退出状态以status_ptr返回。

线程示例程序

  • 用线程计算矩阵的和

    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #define N 4
    int A[N][N], sum[N];
    void *func(void *arg)
    {
        int j, row;
        pthread_t tid = pthread_self();
        row = (int)arg;	
        printf("Thread %d [%lu] computes sum of row %d\n", row, tid, row); 
        for (j=0; j<N; j++)
        {
            sum[row] += A[row][j];
        }
        printf("Thread %d [%lu] done sum[%d] = %d\n",row, tid, row, sum[row]);
        pthread_exit((void*)0);
    }
    
    int main (int argc, char *argv[])
    {
        pthread_t thread[N];	
        int i, j, r, total = 0;
        void *status;
        printf("Main: initialize A matrix\n");
    
        for (i=0; i<N; i++)
        {
            sum[i] = 0;
            for (j=0; j<N; j++)
            {
                A[i][j] = i*N + j + 1;
                printf("%4d" ,A[i][j]);
            }
        printf("\n");
        }
        printf("Main: create %d threads\n", N);
        for(i=0; i<N; i++)
        {
            pthread_create(&thread[i], NULL, func, (void *)i);
        }
        printf("Main: try to join with threads\n");
        for(i=0; i<N; i++) 
        {
            pthread_join(thread[i], &status);
            printf("Main: joined with %d [%lu]: status=%d\n",i, thread[i], (int)status);
        }
        printf("Main: compute and print total sum:"); 
        for (i=0; i<N; i++)
        {
            total += sum[i];
        }
        printf("tatal = %d\n", total); 
        pthread_exit(NULL);
    }
    
  • 用线程快速排序

    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #define N 10
    typedef struct{
        int upperbound;
        int lowerbound;
    }PARM;
    
    int A[N]={5,1,6,4,7,2,9,8,0,3};
    
    int print()	
    {
        int i;
        printf("[ ");
        for (i=0; i<N; i++)
        {
            printf("%d ", A[i]);
        }
        printf("]\n");
    }
    
    void *qsort_1(void *aptr)
    {
        PARM *ap, aleft, aright;
        int pivot, pivotIndex, left, right, temp; 
        int upperbound, lowerbound;
    
        pthread_t me, leftThread, rightThread; 
        me = pthread_self();
        ap = (PARM *)aptr; 
        upperbound = ap->upperbound; 
        lowerbound = ap->lowerbound;
        pivot = A[upperbound]; 
        left = lowerbound - 1; 
        right = upperbound;
        if (lowerbound >= upperbound) 
            pthread_exit(NULL);
    
        while (left < right) 
        {
            do { left++;} while (A[left] < pivot);
                do { right--;}while (A[right] > pivot);
            if (left < right )
            {
                temp = A[left]; 
                A[left] = A[right];
                A[right] = temp;
            }
        }
        print();
        pivotIndex = left; 
        temp = A[pivotIndex]; 
        A[pivotIndex] = pivot; 
        A[upperbound] = temp;
        aleft.upperbound = pivotIndex - 1;
        aleft.lowerbound = lowerbound; 
        aright.upperbound = upperbound; 
        aright.lowerbound = pivotIndex + 1; 
        printf("%lu: create left and right threads\n", me);
        pthread_create(&leftThread, NULL, qsort_1, (void *)&aleft);
        pthread_create(&rightThread, NULL, qsort_1, (void *)&aright);// wait for left and right threads 
        pthread_join(leftThread, NULL); 
        pthread_join(rightThread, NULL); 
        printf("%lu: joined with left & right threads\n", me);
    }
    
    int main(int argc, char *argv[])
    {
        PARM arg;
        int i, *array; 
        pthread_t me, thread; 
        me = pthread_self();
        printf("main %lu: unsorted array =" ,me);
        print();
        arg.upperbound = N-1;
        arg.lowerbound = 0;
        printf("main %lu create a thread to do QS\n", me);
        pthread_create(&thread, NULL, qsort_1, (void *)&arg); // wait for QS thread to finish 
        pthread_join(thread, NULL);
        printf("main %lu sorted array = ", me); 
        print();
    }
    

线程同步

多个线程试图修改同一共享变量或数据结构时,如果修改结果取决于线程的执行顺序,则称之为竞态条件。在并发程序中,绝不能有竞态条件。否则,结果可能不一致。

  • 互斥量

    • 最简单的同步工具是锁,它允许执行实体仅在有锁的情况下才能继续执行。在 Pthread中,锁被称为互斥量,意思是相互排斥。

    • 静态方法

    • 动态方法

  • 死锁预防

    • 互斥量使用封锁协议。

    • 在任何封锁协议中,误用加锁可能会产生一些问题。

    • 死锁是一个状态,在这种状态下,许多执行实体相互等待,无法继续进行下去

  • 条件变量

    • 静态方法

    • 动态方法

  • 生产者-消费者问题
    共享全局变量:

    int buf[NBUF];
    int head,tail;
    int data;
    
  • 信号量

    • 信号量是进程同步的一般机制。

    • 在使用信号量之前,必须使用一个初始值和一个空等待队列进行初始化。

  • 屏障

    • 在 Pthreads中,可以采用的机制是屏障以及一系列屏障函数。
  • 用并发线程解线性方程组

  • Linux中的线程

    • Linux不区分进程和线程。

    • 对于Linux内核,线程只是一个与其他进程共享某些资源的进程。

    • 在 Linux 中,进程和线程都是由 clone()系统调用创建的:

      int clone(int (*fn)(void*),void *child_stack,int flags,void *arg)
      

苏格拉底挑战

关于线程的苏格拉底挑战

关于线程同步的苏格拉底挑战

遇到的问题

问题:线程中,线程调度是如何进行的?
解决方法:问gpt
GPT的回答:

标签:right,int,void,信息安全,笔记,学习,线程,pthread,left
From: https://www.cnblogs.com/wjdnmx/p/17794702.html

相关文章

  • 学习笔记7
    第4章并发编程一、知识点归纳并行计算导论顺序算法与并行算法begin-endcobegin-end并行性与并发性线程原理优点线程创建和切换速度更快线程的响应速度更快线程更适合并行计算缺点线程需要来自用户的明确同步许多库函数可能对线程不安全在单CPU......
  • React学习一:环境搭建、JSX基础、事件绑定、组件使用、样式控制
    一、概念React由Meta公司研发,是一个用于构建Web和原生交互界面的库。react中文文档地址:https://zh-hans.react.dev/learnReact的优势相较传统基于DOM开发的优势:组件化的开发方式;不错的性能相较于其他前端框架的优势:丰富的生态;跨平台支持二、环境搭建首先和vue项目一样,项目......
  • 运用递归学习新知识——插入排序
    还是老样子,先讲一下插入排序的一个概念,比如校合唱团要按身高排队,从左到右由矮到高,小糖同学左边的同学已经按照身高站好了,右边还很乱,于是团长小蓝姐姐想了一个办法,她叫小糖同学往左看,小糖同学左边第一位叫男低1号,左边第二位叫男低2号,右边第一位叫男高1号,右边第二位叫男高2号,以此类......
  • 第八周学习记录
    第四章文件权限4.2基本权限4.2.1ACL的基本用法getfacl命令查看ACL权限,如下图所示: setfacl命令可以设置ACL权限,对每一个文件或目录进行更精确的权限设置,添加“-m”参数可以修改当前文件ACL权限,如下图所示:为用户tom,增加“rwx”权限,使用getfacl命令查看,如下图所示: ......
  • 学习笔记7+代码
    一、苏格拉底挑战二、遇见的问题三、实践和代码代码:#include<stdio.h>#include<pthread.h>//线程函数,接受一个void*参数,返回一个void*指针void*thread_function(void*arg){intthread_arg=*((int*)arg);printf("Threadreceivedargument......
  • Python第二章读书笔记-2023.10.28
    03运行超市抹零结账行为money_all=67.99+11.75+21.1+8.49+25.89+17.5+22.4money_all_str=str(money_all)print("商品总金额为:",money_all_str)money_real=int(money_all)money_real_str=str(money_real)print("实收金额为:",money_real_str)print("学号后四位3126"......
  • 【学习笔记】卡特兰数
    卡特兰数定义:卡特兰数的计算公式涉及组合计数,它是很多组合问题的数学模型,是一个很常见的数列。\(\bf{\underline{卡特兰数(Catalan)}}\)是一个数列,它的一种定义是:\[C_n=\frac{1}{n+1}\binom{2n}{n},n=0,1,2,...\]卡特兰数有三个计算公式:公式1:\[C_n=\frac{1}{n+1}\binom{2n}......
  • 学习笔记7
    第四章并发编程这一章主要介绍了并发编程的相关内容,包括并行计算、顺序算法与并行算法以及并行性和并发性;解释了线程的原理机器相对于进程的优势,同时还进行了线程管理、并发编程的实际操作,让我们更加深刻地了解多任务处理、线程同步和并发编程的原理及方法。并行计算基于分治......
  • 第九周Linux学习笔记
    本周的学习内容属实有点多(差点跟不上,浅浅吐槽一下),学习了第五章进程管理以及第六章I/O重定向。具体命令及其作用在下面一一列举。第五章:进程管理进程小tips:每个进程都有唯一的进程表示PID;进程有就绪态、阻塞态和运行态三个状态;进程有的是密集型有的是疏散型。1、“psaux”命令,......
  • 关于学习Mybatis-plus的认识
    1.实体类的类名和属性尽量一致,如果不一致需要用注解进行指定。2.mybatis-plus是把实体类的类名直接转换成小写到数据库查找,所以需要@TableName(value="表名")来指定表的名字进行查询@TableName("sys_user")publicclassUser{privateLongid;privateStringn......