需要搞明白的几个问题:
1、3次握手和4次挥手
2、TCP与UDP的区别
https://www.cnblogs.com/fundebug/p/differences-of-tcp-and-udp.html
1. 对比
| UDP | TCP |
---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
适用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠传输的应用,例如文件传输 |
2. 总结
- TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务。
- 虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为
- 对数据准确性要求高,速度可以相对较慢的,可以选用TCP
3、如果TCP连接出现问题该如何排查,说明排查的思路
连接断开或者出错,会返回一个错误码,errorNo 最后一次系统调用返回的错误码,来看错误的类型。
4、三元组算法问题
5、查询linux系统中的cup和内存占用率
如果查到具体是哪一个进程占用的比较多,你会怎么做?
如何能够降低程序的cpu或者内存的占用率
6、什么时候使用多线程,什么时候使用多进程
进程与线程的选择取决以下几点:
1、需要频繁创建销毁的优先使用线程;因为对进程来说创建和销毁一个进程代价是很大的。
2、线程的切换速度快,所以在需要大量计算,切换频繁时用线程,还有耗时的操作使用线程可提高应用程序的响应
3、因为对CPU系统的效率使用上线程更占优,所以可能要发展到多机分布的用进程,多核分布用线程;
4、并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求;
5、需要更稳定安全时,适合选择进程;需要速度时,选择线程更好。
https://blog.csdn.net/usstmiracle/article/details/91473004
7、单例模式在什么情况下使用,有什么好处?
单例模式如何实现线程安全?
加了锁就安全了吗?
首先,饿汉式单例模式是线程安全的,但是对于懒汉式单例模式而言就是非线程安全的,那么如何实现线程安全呢?可能大家都会想到加锁,利用sychronized关键字同步方法,这样就可以实现线程安全。
确实这样是可以实现线程安全,但同时会导致效率问题,在java中还有一种方式叫双检查同步啊,首先是利用volatile来实现共享变量的可见性,然后在给变量赋值的时候,再重新检查一下,是否有其他线程改变了这个单例对象。如果没有,则生成单例对象。
8、解决进程互斥访问临界资源的方式有哪几种?各自的优缺点是什么
mutex 互斥量
automic 原子操作
automic int flag;
conditional_variable 条件变量 如读线程用wait( )阻塞和写线程使用notif_all()
需要结合unique_lock
9、什么是原子操作
https://blog.csdn.net/itworld123/article/details/104254626
10、线程池的使用?
11写一个模板类,构造函数和析构函数都是public的为什么?
构造函数本来主要是用来给private的变量赋初值用的,不把构造函数声明在public中,当然就不可以给private赋值了。
再说,不把构造函数声明在public中,外部就不能够调用它了,就失去了它的作用,几乎就没什么用了。析构函数也同理。
智能指针循环引用问题
lock_gurad的使用
多线程,一个线程崩溃了,一个线程正常工作,会不会影响到整个进程?
一个生命周期结束了,分配内存出错了。
是的,线程没有自己的独立空间。
一个进程中可以包含多个线程,他们可以利用进程拥有的资源,
在引入线程的操作系统中,通常都是把进程作为资源分配的基本单元,把线程作为独立运行和独立调度的基本单元。
地址空间和资源:进程间相互独立, 线程间共享
但是据说TLS ,可以实现各线程间相互独立。
-
线程同步,知当软件中要用到多线程,当1号线程运行变量要等待另2号线程的结果时,1号和2号线程就要同步,也就是一个线程要等待另一个线程,或是相互等待。
-
线程安全,比两个或两个以上软件要同时操作(主要指写操作)一个(临界资源)全局变量时,这个时间点不能相同,这样两个线程的操内作会造成程序崩溃,也就是这个状态称为线程不安全(一般用全局信号量来调整两个线程的写入容时间点,防止冲突)
-
线程死锁,当线程为了安全及同步时,用全局信号 量进行相互等待或是相互制约时程序 进入 了一个死锁状态 时(两个线程都停掉了)叫线程死锁。
https://www.cnblogs.com/bj-mr-li/p/11106390.html
https://jingyan.baidu.com/article/597a0643a67dab712b5243a9.html
https://blog.csdn.net/dreamispossible/article/details/91345391
第一次握手:客户端给服务器端发送一个SYN报文;
第二次握手:服务器收到SYN报文之后,会应答一个SYN+ACK报文。
第三次握手:客户端收到SYN+ACK报文之后,会回应一个ACK报文。
服务器收到ACK报文之后,三次握手建立完成。
- 三次握手的作用是为了确认双方的接受和发送能力是否正常。
·第一次握手:客户端发送网络包,服务器收到了。
服务器断就能得到结论:客户端的发送能力、服务端的接收能力是正常的。
·第二次握手:服务端发包,客户端收到了。
客户端就能得出结论:服务端的接收能力、发送能力,客户端的接收、发送能力是正常的。
不过此时服务器并不能确认客户端的接收能力是否正常。
·第三次握手:客户端发包,服务器端收到了。
这样服务端得出结论:客户端的接收能力、发送能力正常,服务器自己的发送能力,接收能力正常。
刚开始客户端处于closed状态,服务端处于Listen状态。
然后:
第一次握手:客户端给服务端发送一个SYN报文,并指明客户端的初始化序列号ISN(c).此时客户端处于SYN_SEND状态。
第二次握手:服务器收到SYN报文后,会以自己的SYN报文作为应答,并且也指定了自己的初始化序列号ISN(S)。同时会把客户端的SYN+1作为ACK的值,表示自己已经收到了客户端的SYN,此时服务器处于SYN_READ状态。
第三次握手:客户端收到SYN报文之后,会发送一个ACK报文,并且也是一样把服务器的ISN+1作为ACK的值,表示已经收到服务端的SYN报文,此时客户端处于establised状态。
服务器收到ACK报文之后,也处于establised状态,此时,双方已经建立起了链接。
步骤阅读
什么时候使用多线程,什么时候使用多进程?
答:首先得知道什么是进程什么是线程?
我的理解是进程是指在系统中正在运行的一个应用程序;程序一旦运行就是进程,
或者更专业化来说:进程是指程序执行时的一个实例。
线程是进程的一个实体。
进程——资源分配的最小单位,
线程——程序执行的最小单位。
线程进程的区别体现在几个方面:
第一:因为进程拥有独立的堆栈空间和数据段,所以每当启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这对于多进程来说十分“奢侈”,系统开销比较大,
而线程不一样,线程拥有独立的堆栈空间,但是共享数据段,它们彼此之间使用相同的地址空间,共享大部分数据,比进程更节俭,开销比较小,切换速度也比进程快,效率高,但是正由于进程之间独立的特点,使得进程安全性比较高,也因为进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。一个线程死掉就等于整个进程死掉。
第二:体现在通信机制上面,正因为进程之间互不干扰,相互独立,进程的通信机制相对很复杂,譬如管道,信号,消息队列,共享内存,套接字等通信机制,而线程由于共享数据段所以通信机制很方便。
3.属于同一个进程的所有线程共享该进程的所有资源,包括文件描述符。而不同过的进程相互独立。
4.线程又称为轻量级进程,进程有进程控制块,线程有线程控制块;
5.线程必定也只能属于一个进程,而进程可以拥有多个线程而且至少拥有一个线程;
第四:体现在程序结构上,举一个简明易懂的列子:当我们使用进程的时候,我们不自主的使用if else嵌套来判断pid,使得程序结构繁琐,但是当我们使用线程的时候,基本上可以甩掉它,当然程序内部执行功能单元需要使用的时候还是要使用,所以线程对程序结构的改善有很大帮助。
进程与线程的选择取决以下几点:
1、需要频繁创建销毁的优先使用线程;因为对进程来说创建和销毁一个进程代价是很大的。
2、线程的切换速度快,所以在需要大量计算,切换频繁时用线程,还有耗时的操作使用线程可提高应用程序的响应
3、因为对CPU系统的效率使用上线程更占优,所以可能要发展到多机分布的用进程,多核分布用线程;
4、并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求;
5、需要更稳定安全时,适合选择进程;需要速度时,选择线程更好。
线程的同步方式有哪几种?各有什么特点?
互斥锁:适用于线程可用的资源只有一个,需要互斥访问的情况
条件变量:适用线程之间构成条件等待关系的情况
conditional_variable
automic 原子操作
读写锁:提高互斥锁在数据库系统数据访问(大量读,较少写)等应用领域的效率
2.1 互斥锁
2.1.1 互斥锁原理
互斥锁以排他方式防止共享数据被并发访问。互斥锁是一个二元变量,只有锁定(禁止1)和解锁(允许0)两种状态,互斥锁可以看作是特殊意义的全局变量,因为在同一时刻只有一个线程能够对互斥锁进行操作。
将某个共享资源与某个特定互斥锁在逻辑上绑定,即要申请该资源必须先获取锁。对该共享资源的访问操作如下:
(1) 首先申请互斥锁,如果该互斥锁处于锁定状态,默认阻塞当前线程;如果处于解锁状态,则申请到该锁并立即占有该锁,使锁处于锁定状态防止其他线程访问该资源。
(2) 只有锁定该互斥锁的线程才能释放该互斥锁,其他线程试图释放操作无效。
2.1.2 互斥锁基本操作函数
功能 函数
初始化互斥锁 pthread_mutex_init
阻塞申请互斥锁 pthread_mutex_lock
非阻塞申请互斥锁 pthread_mutex_trylock
释放互斥锁 pthread_mutex_unlock
销毁互斥锁 pthread_mutex_destroy
使用互斥锁前先定义该互斥锁(全局变量)
pthread_mutex_t lock;
在使用互斥锁以前,必须首先对它进行初始化
静态分配的互斥锁:置为常量PTHREAD_MUTEX_INITIALIZER,属性为NULL,也可以调用pthread_mutex_init函数
动态分配的互斥锁:例如通过调用malloc函数分配的互斥锁,只能调用pthread_mutex_init,且在释放内存前需要调用pthread_mutex_destroy
(1) 初始化互斥锁
int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
形参:
mutex 要初始化的互斥锁的指针
mutexattr 要初始化的互斥锁的属性;NULL表示使用默认属性
其他:也可使用宏初始化静态分配的互斥锁
#define PTHREAD_MUTEX_INITIALIZER {{0,}}
pthread_mutex_t mp = PTHREAD_MUTEX_INITIALIZER;
返回值:成功返回0,否则返回一个错误编号
(2) 销毁互斥锁
调用pthread_mutex_init初始化的互斥锁,在释放内存前需要调用pthread_mutex_destroy
int pthread_mutex_destroy (pthread_mutex_t *mutex);
形参:
mutex 指向要初始化的互斥锁的指针
返回值:成功返回0,否则返回一个错误编号
(3) 阻塞方式申请互斥锁
int pthread_mutex_lock (pthread_mutex_t *mutex);
说明:如果一个线程要占用一个共享资源,必须先申请一个对应的互斥锁
返回值:成功返回0,否则返回一个错误编号
(4) 非阻塞方式申请互斥锁
int pthread_mutex_trylock (pthread_mutex_t *mutex);
返回值:成功返回0,否则返回一个错误编号,以指明错误
(5) 释放互斥锁
int pthread_mutex_unlock (pthread_mutex_t *mutex);
说明:释放操作只能有占有该互斥锁的线程完成
返回值:成功返回0,否则返回一个错误编号
https://blog.csdn.net/baidu_35692628/article/details/69356675
线程间的同步方法大体可分为两类:用户模式和内核模式。
顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,
而用户模式就是不需要切换到内核态,只在用户态完成操作。
用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。
内核模式下的方法有:事件,信号量,互斥量。
1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
2、互斥量:为协调共同对一个共享资源的单独访问而设计的。
3、信号量:为控制一个具有有限数量用户资源而设计。
4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。
延伸阅读:
同步和互斥
当有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源。例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件中的字符数。当然,在把整个文件调入内存之前,统计它的计数是没有意义的。但是,由于每个操作都有自己的线程,操作系统会把两个线程当作是互不相干的任务分别执行,这样就可能在没有把整个文件装入内存时统计字数。为解决此问题,你必须使两个线程同步工作。
所谓同步,是指在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的话,同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。如果用对资源的访问来定义的话,互斥某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
什么是原子操作?
https://blog.csdn.net/itworld123/article/details/104254626
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)