1.并发(concurrency):在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。
并发是指同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上有多个进程被同时执行的效果–宏观上并行,针对单核处理器
其中两种并发关系分别是同步和互斥。
进一步的说明:就是前一个进程的输出作为后一个进程的输入,当第一个进程没有输出时第二个进程必须等待。具有同步关系的一组并发进程相互发送的信息称为消息或事件。(彼此有依赖关系的调用不应该同时发生,而同步就是阻止那些“同时发生”的事情
其中并发又有伪并发和真并发,伪并发是指单核处理器的并发,真并发是指多核处理器的并发。
2.并行(parallelism):在单处理器中多道程序设计系统中,进程被交替执行,表现出一种并发的外部特种;在多处理器系统中,进程不仅可以交替执行,而且可以重叠执行。在多处理器上的程序才可实现并行处理。
从而可知,并行是针对多处理器而言的。并行是同时发生的多个并发事件,具有并发的含义,但并发不一定并行,也亦是说并发事件之间不一定要同一时刻发生。(同一时刻,有多条指令在多个处理器上同时执行–针对多核处理器)
线程是进程的一条执行流,是cpu调度的基本单位,一个进程可以有多个线程;线程是进程中的一条执行流,是CPU调度的基本单位,一个进程中可以有多个线程;
Linux下的线程执行流是通过pcb实现的,且一个进程中可能有多个pcb,并且这些pcb共享同一个进程中的大部分资源,因此,也被称为轻量级进程;
Linux下:
线程:最小的执行单位,调度的基本单位。
进程:资源分配的基本单位,可看成是只有一个线程的进程。
1.2.线程之间的独有与共享
1.3 多进程与多线程多任务处理优缺点分析
共同优点:
多线程进行多任务
线程优点:
(1)共享虚拟地址空间,因此线程间通信更加灵活(还可以通过全局变量、函数传参来实现通信);
(2)线程的创建和销毁成本更低;
(3)同一个进程中的线程调度切换成本更低;
线程缺点:
健壮性低,有些调用和异常是针对整个进程产生的;
例如:exit接口,进程退出会使进程中的所有线程都退出;
大多数情况下,使用多线程,在稳定性要求高的场景中使用多进程;
进程优点:
稳定、健壮性高。(异常导致进程退出,所有线程退出,但不影响其他进程)–主进程安全性要求高的场景–比如:shell、服务器。
linux并没有向上提供用于创建线程的接口。大佬们对系统调用接口进行封装实现了上层用户态的线程控制接口;
2.1.创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
返回值:成功返回0;失败返回非0;
thread:用于获取线程ID;
attr:设置线程属性,设置为NULL,表示默认属性;
start_routine:线程的入口函数;
arg:通过线程入口函数给线程传递的参数;
2.2 线程终止
void pthread_exit(void *retval);
//retcal:返回值
//可以在任意位置,哪个线程调用哪个线程退出;
int pthread_cancel(pthread_t thread);//被动退出
//thread:一个指定的线程ID
//传入谁的ID谁退出;
//返回值:成功返回0,失败返回非0;
注意:主线程退出并不会导致进程退出,只有所有线程退出了进程才会退出;
代码实现
//代码实现:linux下
#include <stdio.h>
#include <pthread.h>
void *thr_entry(void *arg)
{
printf("%s\n", (char*)arg);
while(1) {
printf(" i am normal thread-%p-%d\n", pthread_self(), getpid());
sleep(1);
pthread_exit(NULL);
}
return NULL;
}
int main ()
{
pthread_t tid;
int ret;
char *ptr = "今天的天气好晴朗\n";
pthread_create(获取ID, 属性, 入口函数, 传入参数)
ret = pthread_create(&tid, NULL, thr_entry, (void*)ptr);
if (ret != 0) {
printf("pthread_create failed!\n");
return -1;
}
sleep(2);
pthread_cancel(tid);
while(1) {
printf("i am main thread--%p-%d\n", pthread_self(), getpid());
sleep(1);
}
return 0;
}
2.3.线程等待
线程默认情况下退出后,资源不会被回收,需要被其他线程等待,获取退出线程的返回值释放资源。
线程也不是必须被等待,在线程属性中,有一个分离属性,默认是joinable,处于joinable状态的线程退出后不会自动释放资源,需要被等待;
int pthread_join(pthread_t thread, void **retval);
//thread:线程ID
//**retval: 返回值
//pthread_join是一个阻塞接口
//返回值:成功返回0,失败返回错误码
代码实现
//代码实现,linux
#include<stdio.h>
2 #include<pthread.h>
3 void* thr_entry(void* arg)
4 {
5 char *ptr="hello pthread\n";
6//
7 sleep(3);
8 return (void*)ptr;
9
10 }
11 int main(int argc,int *argv[])
12 {
13 pthread_t tid;
14 int ret=pthread_create(&tid,NULL,thr_entry,NULL);
15 if(ret!=0)
16 {
17 printf("thread create error\n");
18 return -1;
19 }
20
21 //pthread_join(线程id,获取返回值)
22 void *retval=NULL;
23 pthread_join(tid,&retval);
24 printf("retval:%s\n",retval);
25 while(1)
26 {
27 printf("main thread\n");
28 sleep(1);
29 }
30 return 0;
31
32 }
2.4 线程分离
如果你对一个线程的返回值不关心,你也不想去等待这个线程的推出;
设置线程分离属性为detach属性,处于detach属性的线程退出后自动释放资源,不需要被等待;
int pthread_detach(pthread_t thread);
//pthrad:分离线程的id
//可以在任意位置;
pthread_detach(pthread_self());
//pthread_self()函数,获取调用函数id;见下图:
// 线程自己分离
如果不知道,man函数里的左上角()中的数字代表什么,请看上一篇博客;
https://blog.csdn.net/weixin_52270223/article/details/115710222?spm=1001.2014.3001.5501
线程安全等问题清见下一篇博客;**
如有错误或者补充,评论下;互相学习,互关一波,抱拳了
ADO对象: Connection Command Recordset Record Stream ASP支持的对象很多,可...
微信文件传输助手是微信电脑版与手机微信之间相互传输图片等文件的好工具,但很...
计算属性computed: 支持缓存,只有依赖数据发生改变,才会重新进行计算 不支持...
vbs:把一段文字中指定字符颜色变成红色的正则 functionc(Tstr,Word) Dimre Setre...
一、正则表达式概述 二、正则表达式在VBScript中的应用 三、正则表达式在VavaScr...
本文将研究 ES6 的 for ... of 循环。 旧方法 在过去,有两种方法可以遍历 javas...
【排序算法】之lowb三人组冒泡、插入、选择 什么是lowb三人组 冒泡排序bubble so...
前言 相信大家都知道在IDE中代码的智能提示几乎都是标配,虽然一些文本编辑器也...
歌词编辑器 歌词编辑器 第一步:选择要播放的歌曲并播放 第二步:填写全部的歌词...
一石激起千层浪,继中国区浩浩荡荡的大裁员告一段落之后,甲骨文并未因此收起手...