【面经笔记】深信服电话二面

  • 三层的红黑树的根节点删除后,怎么调整

CreateThread 和_beginthreadex的区别? 什么时候应该使用CreateThread 什么时候应该使用_beginthreadex?

CreateThread函数是windows函数,_beginthreadex是C/C++函数。

标准C/C++运行库最初不是为多线程而设计的,所以在多线程环境中会出问题的库变量和函数有很多,如:errno。

为了保证C/C+多线程应用程序的正常运行,必须创建一个数据结构,并使之与使用了C/C++运行库函数的每个线程关联。然后,在调用C/C++运行库函数时,那些函数必须知道去查找主调线程的数据块,从而避免影响到其他线程。(我感觉这有点神似 线程局部存储的概念)

那么,系统在创建新的线程时,如何知道要分配这个数据块呢?答案是不知道,系统并不知道应用程序是用C/C++写的,不知道你调用的函数并非是天生线程安全的。一定不要调用操作系统的CreateThread函数,相反,必须调用C/C++运行库函数_beginthreadex。

_beginthreadex函数在创 建线程的时候分配了一个tiddata堆结构并和线程本身关联起来。tiddata的作用除了保存线程函数入口地址之外,还有一个重要的作用就是: C运行时库中有些函数需要通过这个结构来保存和获取一些数据,比如说errno之类的线程全局变量。

当一个线程调用一个要求tiddata结构的运行时库函数的时候,将发生下面的情况:运行时库函数试图获取线程数据块的地址,如果没有获取到,函数就会 现场分配一个 tiddata结构,并且和线程相关联,于是问题出现了,如果不通过_endthreadex函数来终结线程的话,这个结构将不会被撤销,内存泄漏就会出现了。(对于一个CreateThread函数创建的线程,谁会调用_endthreadex呢?)


Dll的入口函数是什么?

入口函数是DLLMain。

系统是在什么时候调用DllMain函数的呢?静态链接时,或动态链接时调用LoadLibrary和FreeLibrary都会调用DllMain函数。这些调用是通知性质的,通常被DLL用来执行一些与进程或线程有关的初始化和清理工作

DllMain的第一个参数是该DLL实例的句柄,这个值表示一个虚拟内存地址,DLL的文件映像就被映射到进程地址空间中的这个位置。

DllMain的第二个参数fdwReason指明了系统调用Dll的原因,它可能是:
DLL_PROCESS_ATTACH:进程映射
DLL_PROCESS_DETACH:进程卸载
DLL_THREAD_ATTACH:线程映射
DLL_THREAD_DETACH:线程卸载


1、DLL_PROCESS_ATTACH

当系统第一次将一个DLL映射到进程地址空间中时,会调用DllMain,并为fdwReason传入DLL_PROCESS_ATTACH。
注意,只有在第一次映射的时候,才会这样。如之后,另一线程再次显式加载此DLL,则操作系统只是增加该DLL的使用计数,而不会再次使用DLL_PROCESS_ATTACH来调用DllMain。

当一个DLL在处理DLL_PROCESS_ATTACH的时候,应该根据包含在DLL中的函数的需要,执行与进程相关的初始化:如打开资源,分配内存等

DllMain的返回值,也是针对DLL_PROCESS_ATTACH消息的。对于其余的三种取值,不起作用。
对于隐式加载,如DllMain返回FALSE,则程序会启动失败。对于显式加载,则会使LoadLibrary返回NULL。


  • DLL加载过程:

创建新进程时,系统会分配进程的地址空间并将exe的文件映像以及所需DLL文件映像映射到进程的地址空间。然后,系统创建进程的主线程,并用这个线程调用每个DLL 的DLLMain函数,同时传入DLL_PROCESS_ATTACH。当所有已映射的DLL都完成对该通知的处理后,系统会让主线程开始执行可执行模块的C/C++启动时的启动代码,然后执行可执行模块的入口函数(_tmain/_tWinMain)。

  • 显示加载DLL过程:

进程调用LoadLibrary的时候,系统会对DLL进行定位,并将该DLL映射到进程的地址空间中。并使用调用LoadLibrary的线程去调用DLLMain函数,传入DLL_PROCESS_ATTACH。函数返回true,则线程继续正常执行。


2、DLL_PROCESS_DETACH

当系统将一个DLL从进程地址空间中撤销映射时,则会向DllMain传入DLL_PROCESS_DETACH。我们应当在此处放置一些清理代码

当使用FreeLibrary时,如该线程的使用计数为0时,操作系统才会使用DLL_PROCESS_DETACH来调用DllMain。如使用计数大于0,则只是单纯的减少该DLL的计数。


3、DLL_THREAD_ATTACH

当进程创建一个线程,则系统会检查当前已映射到该进程空间中的所有DLL映像,并用DLL_THREAD_ATTACH来调用每个DLL的DllMain。这告诉DLL需要执行与线程相关的初始化。且由新创建的线程负责执行DLLMain函数。

当系统将一个新的DLL映射到进程的地址空间时,如果已经有多个线程在运行,系统也不会让任何已有的线程用DLL_THREAD_ATTACH调用DLLMain函数。

只有当所有DLL都完成了对DLL_THREAD_ATTACH的处理后,新线程才会执行它的线程函数。
另外,主线程不可能用DLL_THREAD_ATTACH来调用DllMain,因为主线程必然是在进程初始化的时候,用DLL_PROCESS_ATTACH调用DllMain的。


4、DLL_THREAD_DETACH

线程若要终止,会调用ExitThread,但是系统不会立即终止线程,而是会让这个即将结束的线程用DLL_THREAD_DETACH来调用当前进程地址空间中的所有DLL镜像的DllMain函数,告诉DLL执行与线程相关的清理工作
当每个DLL的DllMain都处理完后,系统才会真正的结束进程。


DLLMain函数在源码中不是必需的,连接DLL的时候,如果链接器无法在.obj文件中找到名为DLLMain的函数,那么它会链接C/C++运行库的DLLMain函数

如果不提供自己的DllMain,那么C/C++运行库会认为我们不关心DLL_THREAD_ATTACH、DLL_THREAD_DETACH通知。


给你代码,如何优化算法

1)Profile性能分析,找出性能瓶颈,因为80%的时间是在运行20%的代码,找出20%的代码。
2)针对性地修改语法、算法、数据结构、甚至框架,以解决瓶颈。


CUDA编程的详细过程,详细介绍一个算法在cpu和gpu下分别是怎么做的,如何优化CUDA

http://blog.csdn.net/xiaxzhou/article/details/76537473


MFC消息机制 ,各种消息类型

http://blog.csdn.net/xiaxzhou/article/details/76170687


描述TCP三次握手四次挥手,TCP的半关闭、半打开、同时关闭

  • 半关闭

TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。这就是所谓的半关闭
某一端已经完成数据传送,因此发送一个文件结束(FIN)给另一端,但还想接收另一端发送来的数据,直到它给我发送文件结束(FIN)。

  • 半打开

如果一方已经关闭或异常终止连接而另一方却不知道,称为半打开。
处于半打开的连接,如果双方不进行数据通信,是发现不了问题的,只有在通信时才真正的察觉到这个连接已经处于半打开状态,如果双方不传输数据的话,仍处于连接状态的一方就不会检测另外一方已经出现异常。

这样会导致服务器主机产生很多半打开的TCP连接,通过保活定时器可以使TCP的一端发现另一端已经消失:http://www.cnblogs.com/youxin/p/4056041.html

它每隔一段时间会超时,超时后会检查连接是否空闲太久了,如果空闲的时间超过了设置时间,就会发送探测报文。然后通过对端是否响应、响应是否符合预期,来判断对端是否正常,如果不正常,就主动关闭连接,而不用等待HTTP层的关闭了。
当服务器发送探测报文时,客户端可能处于4种不同的情况:仍然正常运行、已经崩溃、已经崩溃并重启了、由于中间链路问题不可达。在不同的情况下,服务器会得到不一样的反馈。

  • 同时关闭

上述为一方先发送第一个FIN执行主动关闭。双方都执行主动关闭也是可能的。TCP协议允许这样的同时关闭

如果应用程序同时发送FIN,则在发送后会首先进入FIN_WAIT_1状态。在收到对端的FIN后,回复一个ACK,会进入CLOSING状态。在收到对端的ACK后,进入TIME_WAIT状态。

同时关闭时两端都会进入TIME_WAIT状态。

http://blog.csdn.net/huoqubing/article/details/6126189


  • 项目的最大难点在哪里,给你一个新任务,你如何去完成?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值