IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> process-thread -> 正文阅读

[系统运维]process-thread

一、进程的概念:
执行一个程序所分配的资源的总称,进程是程序的一次执行过程动态的,包括创建、调度、执行和消亡
程序就是我们写好的代码,编译成可执行文件后成为程序,存放在硬盘里面。

但是,当我们点击./a,out去执行的时候,它运行起来:把硬盘程序数据读到内存中,占用的cpu资源。等等运行所要的资源的总称,称为进程。
PCB:进程控制块
我们的进程是由一个一个进程链表的来管理的,这个表叫进程控制块PCB,里面有进程标识pid,进程用户,进程状态,,优先级文件描述符表的信息。通过唯一标识pid号进行管理,这个pid其实和fd文件描述符的用法类似,就是一个结构体下标。

一个进程有四种状态:运行态(正常就是运行态) ,等待态(休眠),停止态()进程被命令中止,僵尸态(进程已经被中止,但是pcb资源没有被回收)

进程创建

#include  <unistd.h>
 pid_t  fork(void);
创建新的进程,失败时返回-1
成功时父进程返回子进程的进程号,子进程返回0
通过fork的返回值区分父进程和子进程

子进程继承了父进程的内容
父子进程有独立的地址空间,互不影响
若父进程先结束
子进程成为孤儿进程,被init进程收养
子进程变成后台进程
若子进程先结束
父进程如果没有及时回收,子进程变成僵尸进程

进程回收:
子进程结束时由父进程回收
孤儿进程由init进程回收
若没有及时回收会出现僵尸进程

回收全部子进程
 #include  <unistd.h>
 pid_t wait(int *status); 
 成功时返回回收的子进程的进程号;失败时返回EOF
 若子进程没有结束,父进程一直阻塞
 若有多个子进程,哪个先结束就先回收
 status 指定保存子进程返回值和结束方式的地址
 status为NULL表示直接释放子进程PCB,不接收返回值
 回收指定进程:
 #include  <unistd.h>
  pid_t waitpid(pid_t pid, int *status, int option);
   
 成功时返回回收的子进程的pid或0;失败时返回EOF
  pid可用于指定回收哪个子进程或任意子进程
 status指定用于保存子进程返回值和结束方式的地址
 option指定回收方式,0 或 WNOHANG

二、线程的概念;
由于进程间通信数据交互非常麻烦且进程开销非常大。所以我们引入了线程的概念。线程是轻量级的进程:
linux其实不区分进程和线程:他们都是一个task_struct链表来管理。
进程右不同的pid号,同一进程下所有线程都共享同一个pid。并且就算你不创建线程,那么进程里面也会有一个线程。就是你一个./a.out这个进程,执行mian函数即是一个进程也是一个线程。多线程下的task_structlm里面的pid号是一样的。

线程的好处:
大大提高了任务切换的效率
避免了额外的TLB & cache的刷新

线程的创建:

#include  <pthread.h>
 int  pthread_create(pthread_t *thread, const
       pthread_attr_t *attr, void *(*routine)(void *), void *arg);

 成功返回0,失败时返回错误码
 thread 线程对象
 attr 线程属性,NULL代表默认属性
 routine 线程执行的函数
 arg 传递给routine的参数 ,参数是void * ,注意传递参数格式,

pthread_t  pthread_self(void)   查看自己的TID

创建一个线程去处理 void *(*routine)(void *)这个函数,处理完毕,线程结束并注销。如果进程结束,那么所有的线程都结束,不管你的程序有没有执行完。一个线程用exit();退出,所有的线程都会退出。exit()直接退出程序。

线程的回收:

#include  <pthread.h>
 int  pthread_join(pthread_t thread, void **retval);
       
 成功返回0,失败时返回错误码
 thread 要回收的线程对象
 调用线程阻塞直到thread结束
 *retval 接收线程thread的返回值

线程的取消:

int pthread_cancel(pthread_t thread);

取消是停止线程但是资源没有释放
线程的结束:

 #include  <pthread.h>
 void  pthread_exit(void *retval);
       
 结束当前线程
 retval可被其他线程通过pthread_join获取
 线程私有资源被释放

——————————————————————————————————————————————
三、线程间的同步和互斥
线程间的同步:
信号量
适用于,当某事件发生后,另一个事件才能发生的情况:例如:
我一个线程要往一个buf里面写数据,我另一个线程要读数据。
肯定要先写才能读数据啊,所以我可以定义一个信号量,起始信号量为0 ,用于信号的同步,当我写好之后我的信号量+1,这样就可以读数据了。读完信号量减一。这样就不能再次读数据了。

信号量操作:

1)初始化信号量:
 #include  <semaphore.h>
 int  sem_init(sem_t *sem, int pshared, unsigned int val);
 成功时返回0,失败时EOF
 sem  指向要初始化的信号量对象
 pshared   0 – 线程间   1 – 进程间
 val  信号量初值

2)信号量的P/V操作:
 #include  <semaphore.h>
 int  sem_wait(sem_t  *sem);       P操作
 int  sem_post(sem_t  *sem);       V操作
 成功时返回0,失败时返回EOF
 sem  指向要操作的信号量对象

线程间的互斥:
锁机制:mutex
适用于:多线程访问共享资源时,对共享资源上锁。让其它线程不可访问。以避免出现数据紊乱的情况。

比如我一个线程在往一个buf里面写数据
我另一个也在往buf里面写数据
因为线程是并行的,这样这个数据你永远都预测不到它长什么样子了
一个线程申请锁后必须释放锁。
要不然共享资源就变成你家的资源了,别人都用不了。

初始化锁:
#include  <pthread.h>
 int  pthread_mutex_init(pthread_mutex_t *mutex,
       const pthread_mutexattr_t *  attr);
 成功时返回0,失败时返回错误码
 mutex  指向要初始化的互斥锁对象
 attr  互斥锁属性,NULL表示缺省属性

2)申请锁
#include  <pthread.h>
 int  pthread_mutex_unlock(pthread_mutex_t *mutex);

 成功时返回0,失败时返回错误码
 mutex  指向要初始化的互斥锁对象
 执行完临界区要及时释放锁

3)释放锁
#include  <pthread.h>
 int  pthread_mutex_unlock(pthread_mutex_t *mutex);

 成功时返回0,失败时返回错误码
 mutex  指向要初始化的互斥锁对象
 执行完临界区要及时释放锁

——————————————————————————————————
多进程与多线程的比较:

进程:
进程有独立的地址空间
Linux为每个进程创建task_struct
每个进程都参与内核调度,互不影响

线程:
进程在切换时系统开销大
很多操作系统引入了轻量级进程LWP
同一进程中的线程共享相同地址空间
Linux不区分进程、线程

多线程共享的资源:
一个进程中的多个线程共享以下资源:
可执行的指令
静态数据
进程中打开的文件描述符
当前工作目录
用户ID
用户组ID

线程间私有的资源:
每个线程私有的资源包括:
线程ID (TID)
PC(程序计数器)和相关寄存器
堆栈
错误号 (errno)
优先级
执行状态和属性

什么时候适用多进程,什么时候使用多线程:

1、首先你得理解多进程的怎么执行的?它是怎么做到多线程并行的。
这个问题其实,多线程是假的并行,根据时间片,一会执行这个线程,一会执行另一个线程。其实他是一个时间处理一条语句,然后时间片轮转着去执行各线程的语句。这比较费时间。
类似于:单核的多进程
时间片轮询进程调度算法,它的思想简单介绍如下: 在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如10毫秒),这样用户根本感觉不出来CPU是在轮流为多个进程服务,就好象所有的进程都在不间断地运行一样。但实际上在任何一个时间内有且仅有一个进程占有CPU及CPU的运算器。

2多进程的实现:
要是你的进程数小于cpu的核数。比如我exynos4412这个板子是4核的,买手机的时候会看的参数就是什么四核,八核。就是cpu的个数。要是你的进程数小于cpu的核数。那么你的进程就可以做到真正的并发。就是在同一时间片下,会有1,2,3,4等进程同时执行程序的可能。要是进程数大于ccpu核数,那么也将采用 ——时间片轮询进程调度算法。不过有四各时间片可以调度。

结合上面的多进程多线程的实现,以及线程核进程的特性:

如果你想要少消耗资源:多线程

如果你两个程序要频繁交互数据:多线程

如果你想要两程序间数据少交互为了安全:多进程

如果你想要程序跑的快:多进程

选择多进程核多线程要更据实际来选。

比如我做到安防监控的item。我绝对一个选多进程核多线程一起用:

我数据有上行把zigbee的数据交给web。数据下行有web发送命令到硬件实现控制。
那么这上行,和下行完全不用数据交互,而且我的开发板有足够多的空间,而且总共的进程有:cgi 上下行。好像才三个。不过好像还有boa,那这样也才4个进程。我开发板是4核的牛逼。所以在总的A9框架上我选择fork多进程。
然后我数据采集进程要采集很多一个的数据,这时候我就采用多线程。nice————

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:53:40  更:2021-10-12 23:54:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 18:51:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码