这里是一部分内容,还会做修改。

一:目的及内容

学习fork(),exec,pthread库函数的使用,阅读源码,分析fork,exec,pthread_create函数的机理

代码实现:

进程A创建子进程B

子进程B与父进程A分别对应不同的可执行体:A打印Hello world,B实现sum累加

进程B具有三线程,主线程创建新的线程1实现sum累加(从1到参数x),线程2监控输入参数x

若输入x是非负整数,线程1开始计算;如果线程1正在计算前次程序,线程2的输入非负整数和最近一次的又不同,线程1应重新计算;若相同则不需要重新计算

若输入字母p,则线程1暂停执行。

输入字母e则线程1打印退出信息后整个进程A和B都退出

若输入的是其他字符,则线程1打印一个输入错误提示,任务继续

分析运行中各个执行体的处理器使用,内存使用等基本信息

二 步骤

参考

Linux C编程--fork()详解 - 张勤一 - CSDN博客

[并发并行]_[pthread]_[对工作线程进行简单控制-暂停-继续-停止] - 心如止水 - CSDN博客

Linux多任务编程(三)---exec函数族及其基础实验 - 王大壮的博客 - CSDN博客

Linux多线程编程并传递多个参数实例 - blankqdb - 博客园

有关pthread线程的暂停与恢复的讨论 - 一天 一小步 - CSDN博客

根据题目要求,可知需要两个执行体A和B。根据模块化的原则先设计A,再设计B。

1. 审题,根据题目要求,写了进程A的代码

#include提供fork(),execlp()函数

#include <sys/wait.h> 提供wait()函数

#include 提供类型pid_t的定义

代码比较简单,主要就是创建子进程,子进程用一个新的进程映像替换当前进程映像。

 

2. 之后写子进程B的代码

充分利用模块化的设计方法。

先是头文件

#include<pthread.h>提供pthread库函数

而需要注意,gcc编译时加上-lpthread,因为pthread并非Linux默认的库

 

之后是几个全局变量,减少线程间传递参数的麻烦。

 

1.主线程

功能是创建2个子线程,线程2监控输入,线程1打印信息和计算累加。

当线程1,2都退出后主线程退出。

使用pthread_create创建子线程。

使用pthread_join等待线程结束

 

2.线程2

因为线程2要监控输入,所以先写线程2.

线程2第一部分:

主要进行输入的处理。

详情见图片和代码的注释。

这里用c++的string处理输入,因为没有限制输入类型

 

线程2第二部分:

根据输入确定func值。func作为全局变量调整线程1的工作状态

同时根据recent和cal判断是否要重新计算。target是线程1从1开始的累加目标。

 

线程2第三部分:

根据第二部分得到的func调整线程1工作状态。

func==2时,利用pthread_join()先等待线程1打印错误信息,再退出。

pthread_suspend()  pthread_resume()函数是自己定义的函数,用以实现线程1暂停。暂停的实现具体解释见实验报告后续部分。

 

3. 线程1

第一部分:实现线程1的暂停。

利用

pthread_mutex_lock(),pthread_mutexunlock(),pthread_cond_wait(),pthread_cond_broadcast()实现线程的暂停。

源码体现的暂停实现过程更清晰。

 

 

 

第二部分:线程1进行累加,输出信息等操作

sleep是为了体现p操作,两次输入相同,不同操作而设置。否则可能人输入的速度不如计算机计算速度,导致第二次输入还没到,就得出上一次的结果。

 

综上,进程B结构如下

void pthread_suspend(void)

void pthread_resume(coid)

void thread1(void* arg)

void thread2(void*arg)

int main()

三.分析运行中各个执行体的处理器使用,内存使用等基本信息

首先在终端运行进程A。

 

pgrep 是通过程序的名字来查询进程的工具,一般是用来判断程序是否正在运行。在服务器的配置和管理中,这个工具常被应用,简单明了;

然后打开另一个终端,pgrep -l A查看进程名和pid

 

pstree -p 26638。以树状图显示进程,并显示进程pid。可见父子进程和线程的关系。

 

ps -T -p 26639 可以查看进程B的线程信息。

 

使用top查看进程cpu和内存信息。

下图为示例:

 

top命令的第三行,cpu状态:

依次对应:

us:user 用户空间占用cpu的百分比

sy:system 内核空间占用cpu的百分比

ni:niced 改变过优先级的进程占用cpu的百分比

id:空闲cpu百分比

wa:IO wait IO等待占用cpu的百分比

hi:Hardware IRQ 硬中断 占用cpu的百分比

si:software 软中断 占用cpu的百分比

st:被hypervisor偷去的时间

top命令第四行,内存状态:

total,free ,used ,buff/cache

依次对应:物理内存总量,空闲内存总量,使用中的内存总量,缓冲内存量

进入top后,交互时,输入s,系统提示更改刷新间隔。输入0则不断刷新。

 

top -p 26638查看pid为26638的进程(即A)的信息

 

top -p - H 26639

top命令可以实时显示各个线程情况。要在top输出中开启线程查看,请调用top命令的“-H”选项,该选项会列出所有Linux线程。在top运行时,你也可以通过按“H”键将线程查看模式切换为开或关。

 

四 遇到的问题及解决:

1.编译时出现c++11标准库未定义错误,因为编译器使用的库版本不同。

 

 

解决:使用-l链接 stdc++

 

2. gcc编译时报错

 

解决:

在32位模式时,int 和指针类型变量都占32位在64位模式下,int占32位,指针变量占64位

 

3.如图

 

又是-lstdc++解决

五.实验结果记录:

执行程序A。程序A 父进程fork 出子进程,之后打印Hello, world!然后执行wait(),等待子进程结束。

子进程调用execlp,执行另一个执行体B。

执行体B中线程2开始监控输入。

输入15,是非负整数,之后线程1计算1累加到15.结果为120。120后跟着的15表明计算的是1-15累加。

输入16,是非负整数,之后线程1计算1累加到16.结果为136。136后跟着的16表明计算的是1-16累加。

输入18,之后输入20.线程2监控到由于20与18不同,故线程1不再进行1-18累加,而进行1-20累加。

输出210.

输入25,再输入25.线程2监控到25相同,不需要重新计算,打印信息“输入相同,不需要重新计算”。线程1计算第一个25,输出325.

输入afd。线程2监控,属于其他字符,线程1打印错误信息“input wrong”。

输入fg。线程2监控,属于其他字符,线程1打印错误信息“input wrong”。

输入p,线程1暂停执行。打印信息“pause”表明线程1已暂停。

输入123.线程2检测到是非负整数,先调用恢复函数解除线程1的暂停。之后打印信息“resume”表示线程1已经恢复。之后线程1执行1-123累加,输出7626.

输入e。线程2检测到要退出。之后线程1打印信息“A and B exited”表示主进程,子进程都要退出。之后主进程和子进程都退出。

结束。

操作系统:Linux进程与线程的更多相关文章

  1. Linux进程和线程的比較

    进程与线程 參考:http://www.cnblogs.com/blueclue/archive/2010/07/16/1778855.html 首先比較Linux进程和线程的创建的差别,以此展开: ...

  2. Linux进程或线程绑定到CPU

    Linux进程或线程绑定到CPU 为了让程序拥有更好的性能,有时候需要将进程或线程绑定到特定的CPU,这样可以减少调度的开销和保护关键进程或线程. 进程绑定到CPU Linux提供一个接口,可以将进程 ...

  3. Linux 进程、线程运行在指定CPU核上

    /******************************************************************************** * Linux 进程.线程运行在指定 ...

  4. LINUX操作系统知识:进程与线程详解

    当一个程序开始执行后,在开始执行到执行完毕退出这段时间内,它在内存中的部分就叫称作一个进程. Linux 是一个多任务的操作系统,也就是说,在同一时间内,可以有多个进程同时执行.我们大家常用的单CPU ...

  5. linux进程、线程与cpu的亲和性(affinity)

    参考:http://www.cnblogs.com/wenqiang/p/6049978.html 最近的工作中对性能的要求比较高,下面简单做一下总结: 一.什么是cpu亲和性(affinity) C ...

  6. Linux进程与线程的区别

    进程与线程的区别,早已经成为了经典问题.自线程概念诞生起,关于这个问题的讨论就没有停止过.无论是初级程序员,还是资深专家,都应该考虑过这个问题,只是层次角度不同罢了.一般程序员而言,搞清楚二者的概念, ...

  7. (笔记)linux 进程和线程的区别

    进程:进程是程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集.从内核的观点看,进程的目的就是担当分配系统资源(CPU时间.内存等)的基本单位. 线程:线程是进程的一个执行流,是CPU ...

  8. Python开发——13.操作系统、进程和线程

    一.操作系统 1.定义 操作系统是用来协调.管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间.操作系统运行在内核态,拥有对所有硬件的完全访问权,可以执行机器能够运行的任何指令.软件的 ...

  9. linux进程与线程的区别【转】

    知乎上总结: "linux使用的1:1的线程模型,在内核中是不区分线程和进程的,都是可运行的任务而已.fork调用clone(最少的共享),pthread_create也是调用clone(最 ...

随机推荐

  1. oracle dataguard搭建

    搭建前环境准备 1.查看主库的oracle的uid和gid并在备库创建用户 # 主库查看oracle $ id oracle uid=54321(oracle) gid=54321(oinstall) ...

  2. 【JAVA并发第三篇】线程间通信

    线程间的通信 JVM在运行时会将自己管理的内存区域,划分为不同的数据区,称为运行时数据区.每个线程都有自己私有的内存空间,如下图示: Java线程按照自己虚拟机栈中的方法代码一步一步的执行下去,在这一 ...

  3. 用SAP浏览网页

    在SAP里,通过两个类就可以做一个简单的,嵌入sap里的网页.这两个类就是 1. cl_gui_custom_container 这个类是自定义屏幕里用得,也就是画一个container,在这个容器中 ...

  4. 前端知识(一)04 Vue.js入门-谷粒学院

    目录 一.介绍 1.Vue.js 是什么 2.初识Vue.js 二.基本语法 1.基本数据渲染和指令 2.双向数据绑定 3.事件 4.修饰符 5.条件渲染 6.列表渲染 7.实例生命周期 一.介绍 1 ...

  5. java之 Request

    0x01.Request 什么是request 在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息. ...

  6. python系统监控及邮件发送

    python系统监控及邮件发送   #psutil模块是一个跨平台库,能轻松实现获取系统运行的进程和系统利用率   import psutil                              ...

  7. 在这个应用中,我使用了 MQ 来处理异步流程、Redis 缓存热点数据、MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ、MySQL 持久化的数据也会存在于一个分布式文件系统中,他们之间的调用也是需要用 RPC 来完成数据交互的。

    在这个应用中,我使用了 MQ 来处理异步流程.Redis 缓存热点数据.MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ.MySQ ...

  8. GC 卡顿 优化 三色标记优势

    小结: 1. 三色标记的一个明显好处是能够让用户程序和 mark 并发的进行 Go GC 卡顿由秒级降到毫秒级以下:到底做了哪些优化? https://mp.weixin.qq.com/s/2BMGG ...

  9. Atlas 2.1.0 实践(4)—— 权限控制

    Atlas的权限控制非常的丰富,本文将进行其支持的各种权限控制的介绍. 在atlas-application.properties配置文件中,可以设置不同权限的开关. atlas.authentica ...

  10. 学习SpringBoot,整合全网各种优秀资源,SpringBoot基础,中间件,优质项目,博客资源等,仅供个人学习SpringBoot使用

    学习SpringBoot,整合全网各种优秀资源,SpringBoot基础,中间件,优质项目,博客资源等,仅供个人学习SpringBoot使用 一.SpringBoot系列教程 二.SpringBoot ...