labweek11

实验报告

实验内容

线程(1):

编译运行课件 Lecture13 例程代码:

Algorithms 13-1 ~ 13-8.

实验环境

 Ubuntu 20.04.2.0(64位)

实验过程

一. alg.13-1-pthread-create-1-1.c

 (一)对代码中不熟悉的内容进行解析:

  1. pthread_attr_init()参考资料

头文件#include<pthread.h>

函数原型int pthread_attr_init(pthread_attr_t *attr);

函数功能: 初始化一个线程对象的属性。

参数:

attr:指向一个线程属性结构的指针

返回值: 返回0,表示函数初始化对象成功。失败时返回一个错误代码。

  1. pthread_create()参考资料

头文件#include<pthread.h>

函数原型int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, void *(*start_rtn)(void*),void *arg);

函数功能: 创建线程

参数:

tidp: 指向线程标识符的指针

attr: 用来设置线程属性

(start_rtn)(void): 线程运行函数的起始地址

arg: 运行函数的参数

返回值: 若线程创建成功,则返回0。若线程创建失败,则返回出错编号。

  1. pthread_join()参考资料

函数原型int pthread_join(pthread_t thread, void **retval);

函数功能: 用来等待一个线程的结束,线程间同步的操作

参数:

thread: 线程标识符

retval: 用户定义的指针,用来存储被等待线程的返回值

返回值: 0代表成功。失败,返回的则是错误号

  1. pthread_exit()参考资料

函数原型void pthread_exit(void* retval);

参数:

retval: 用户定义的指针,用来存储被等待线程的返回值

 (二)运行

在这里插入图片描述

  1. 程序先通过 pthread_create(&ptid, &attr, &runner, argv[1]) 创建了一个线程。该线程执行函数 static void *runner(void *param),传入参数为 argv[1]

  2. 主线程 main() 继续执行直到函数 pthread_join(ptid, (void **)&retptr),挂起,等待子线程 ptid 结束。

  3. 子线程执行,通过 pthread_exit((void *)retptr) 结束线程,返回指定参数。

  4. 主线程继续执行直到结束,在子线程中申请的内存(返回参数的内存)要在主线程中释放。

二. alg.13-1-pthread-create-1-2.c

 (一)运行
在这里插入图片描述

该程序的运行与程序一一致,区别是将计算的结果(全局变量的指针)作为子线程的返回值。

三. alg.13-1-pthread-create-1-3.c

 (一)运行

该程序的运行与程序一一致,区别是不使用全局变量,而是通过主线程中的指针来传递计算结果。

四. alg.13-1-pthread-create-2.c

 (一)运行
在这里插入图片描述

该程序的运行与程序一一致,区别是返回的指针类型为char。

五. alg.13-1-pthread-create-3-1.c

 (一)运行
在这里插入图片描述

主线程根据用户输入的参数创建相应数量的子线程(运行函数 static void *ftn(void *arg)),由于每创建一个线程后会 sleep 1秒,所以线程在创建时标号不会乱且不会重复。

主线程等待所有子线程结束后再继续执行。

六. alg.13-1-pthread-create-3.c

 (一)运行
在这里插入图片描述

该程序的运行与程序四一致,区别是创建线程时不 sleep,导致线程在创建时标号发生混乱和重复。

七. alg.13-1-pthread-create-4.c

 (一)运行
在这里插入图片描述

该程序的运行与程序四一致,区别是创建线程时不 sleep,但先给每个线程分配好了标号,因此线程在创建时标号不会重复。

八. alg.13-1-pthread-create.c

 (一)运行
在这里插入图片描述

该程序的运行与程序一一致,区别是子线程结束时不返回任何参数。

九. alg.13-2-pthread-shm.c

 (一)运行
在这里插入图片描述

通过子线程来改变共享内存的内容。子线程1改变msg1的内容,子线程2改变msg2的内容。

十. alg.13-3-pthread-stack.c

 (一)对代码中不熟悉的内容进行解析:

  1. pthread_attr_setstack()参考资料

头文件#include<pthread.h>

函数原型int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);

函数功能: 设置栈的属性

参数:

attr:指向一个线程属性结构的指针

stackaddr: 要写入 attr 指向的 stack address

stacksize: 要写入 attr 指向的 stack size

返回值: 返回0,表示函数成功。失败时返回一个错误代码。

 (二)运行
在这里插入图片描述

先设置线程的栈属性,然后测试创建的线程的栈的大小。

十一. alg.13-4-openmp-demo.c

 (一)对代码中不熟悉的内容进行解析:

  1. #pragma omp parallel

头文件#include <omp.h>

功能: 其后大括号中的语句将被多个线程并行执行,线程个数由系统预设或自行设置。

 (二)运行
在这里插入图片描述

1由2个线程(系统自行预设)并行执行;2由2个线程(用户设置)并行执行;3由4个线程(用户设置)并行执行;4由6个线程(用户设置)并行执行。

十二. alg.13-5-openmp-matrixadd.c

 (一)运行
在这里插入图片描述

比较不同线程下矩阵加法的运算时间。

可以看到当矩阵的规模较小时,单线程所用时间更短,此时多线程的创建开销不划算。

当矩阵规模较大时,2个线程的计算时间更短,此时创建2个子线程的开销是值得的。

而4个线程的计算时间总是相对最长的,猜测是矩阵的规模还不够大,无法弥补创建4个子线程的开销。

十三. alg.13-6-fork-pthread-demo1.c

 (一)运行
在这里插入图片描述

先创建一个线程在 fork,子进程只会从 fork 处继续往下执行,因此此时是三个进程。子进程结束后就只剩下两个进程。

由于父进程没有等待子线程结束,因此父进程结束时子线程仍在运行(循环),需要手动终止它。

十四. alg.13-7-fork-pthread-demo2.c

 (一)运行

在这里插入图片描述

先创建一个子线程,然后在子线程中 fork,由于父线程直接 return 1 结束父线程及其创建的子线程,因此子线程 fork 出来的线程一直处于运行状态。需要通过命令 pkill -f a.out 才能结束其运行。

return 1 去掉再运行。
在这里插入图片描述

父线程创建的子线程和子线程 fork 出来的线程同时在运行,此时父线程挂起,等待子线程结束。

十五. alg.13-8-sigaction-demo.c

 (一)对代码中不熟悉的内容进行解析:

  1. sigemptyset()参考资料

头文件#include<signal.h>

函数原型int sigemptyset(sigset_t *set);

函数功能: 用来将参数set信号集初始化并清空。

返回值: 执行成功则返回0,如果有错误则返回-1

  1. sigaddset()参考资料

头文件#include<signal.h>

函数原型int sigaddset(sigset_t *set,int signum);

函数功能: 用来将参数signum 代表的信号加入至参数set 信号集里。

返回值: 执行成功则返回0,如果有错误则返回-1

  1. sigaction()参考资料

头文件#include<signal.h>

函数原型int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);

函数功能: 检查或修改与指定信号相关联的处理动作(可同时两种操作)

参数:

signum:指出要捕获的信号类型

act:指定新的信号处理方式

oldact:输出先前信号的处理方式(如果不为NULL的话)

返回值: 执行成功则返回0,如果有错误则返回-1

 (二)运行
在这里插入图片描述
等待抓取到按键 Ctrl + c

抓取到 Ctrl + c 后
在这里插入图片描述

睡眠10秒后
在这里插入图片描述
等待抓取到按键 Ctrl + \

抓取到 Ctrl + \ 后,成功退出。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
疫情居家办公系统管理系统按照操作主体分为管理员和用户。管理员的功能包括办公设备管理、部门信息管理、字典管理、公告信息管理、请假信息管理、签到信息管理、留言管理、外出报备管理、薪资管理、用户管理、公司资料管理、管理员管理。用户的功能等。该系统采用了MySQL数据库,Java语言,Spring Boot框架等技术进行编程实现。 疫情居家办公系统管理系统可以提高疫情居家办公系统信息管理问题的解决效率,优化疫情居家办公系统信息处理流程,保证疫情居家办公系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理疫情居家办公系统信息,包括外出报备管理,培训管理,签到管理,薪资管理等,可以管理公告。 外出报备管理界面,管理员在外出报备管理界面中可以对界面中显示,可以对外出报备信息的外出报备状态进行查看,可以添加新的外出报备信息等。签到管理界面,管理员在签到管理界面中查看签到种类信息,签到描述信息,新增签到信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值