- 浏览: 258652 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (263)
- mysql (5)
- boost (6)
- 工具 (10)
- IT生活 (7)
- 多线程 (3)
- Ruby (15)
- php (2)
- MongoDB (39)
- 移动互联网 (2)
- 测试 (8)
- c++ (28)
- 书 (1)
- 网站 (3)
- 网络编程 (14)
- 开源软件 (1)
- 分布式计算 (1)
- 得得得 (1)
- php,wordpress (1)
- error (5)
- 编译 (2)
- 学习 (1)
- 杀毒软件 (1)
- dd (0)
- linux (21)
- 数据库 (1)
- STL (1)
- c++/c (5)
- 软件设计 (1)
- 操作系统 (4)
- 库 (2)
- win32 (1)
- s (0)
- openssl (1)
- perl (2)
- debug (1)
- windows (4)
- python (12)
- windows 防火墙 (1)
- vs (1)
- vim (2)
- vc (1)
- 浏览器插件的危害 (1)
- curl (0)
- 判断手机号码合法性的库 (0)
- 地址备注 (0)
- 安装 File::Slurp (1)
- cenos (2)
- shell (1)
- linunx (1)
- internet (1)
- software (1)
- widows (1)
- linux io (1)
- nginx (2)
- 算法 (2)
- google (1)
- protobuf (2)
- tengine (1)
- tools (1)
- lua (2)
- liunx (1)
- vcard (1)
- lua-iconv (1)
- 网络 (2)
- teat (0)
- ldconfig linux (0)
- awk (0)
- grep (0)
- windws (2)
- linux 命令 (1)
- tcp dump (1)
- vmware (1)
- question2answer (2)
- mongdb (1)
- 正则 (1)
- OCR (2)
- Windows Server (1)
最新评论
利用_beginthreadex创建的线程句柄不会自动释放,如果反复大量建线程,达到 15,0000个时,用socket发送数据时会发生10055的错误。
线程基本概念
1.线程的组成
(1)线程内核对象:用于管理线程及存储线程的统计信息
(2)线程栈:维护线程执行时需要的函数参数和局部变量。 线程栈所需的内存是从进程中分配而得的,其大小默认是1M.
每个线程都有自已独立的线程栈。
进程不执行任何代码,所有的代码都是由线程执行的。进程相当于一个装载线程的容器。
线程共享进程的地址空间和数据,如内核对象句柄(内核对象句柄只能依附于某个进程而不是某个线程)
2.线程函数原型
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
DWORD dwResult = 0;
...
return(dwResult);
}
The system allocates memory out of the process' address space for use by the thread's stack.
3.终止线程
1.线程正常退出。系统会对线程函数内创建的所有对象调用析构函数。
2.ExitThread(). 线程退出, 系统会清理线程栈。 但是系统不会对线程函数内创建的所有对象调用析构函数。
3.TerminateThread().线程异步退出,系统不清理线程栈。只到拥有该线程的进程退出时才清理线程栈。
该函数是个异步函数,它只会告诉系统去杀掉某个线程,但是系统不会保证当该函数返回时线程立刻终止。
因此我们如果我们要确认线程已经终止了,则需要用WaitForSingleObject()来等待线程结束。
4.内核对象由进程所拥有,用户对象由线程拥有。线程可拥有两种用户对象:Windows和Hook.
5.线程终止后,线程所拥有的用户对象会被系统释放。
6.GetExitCodeThread() //检查线程是否已终止
4.线程内部细节
1.CreateThread 和 _beginthreadex 区别:
CreateThread是系统API,_beginthreadex是CRT(C Run Time Library 运行时库)函数. _beginthreadex内部会调用CreateThread函数。
_endthreadex会释放_beginthreadex为tiddata结构分配的内存。
如果线程函数中调用了CRT函数(注:不是全部CRT函数 只是其中一部分函数),则该线程函数必须由_beginthreadex而不是CreateThread函数创建。否则会产生内存泄露。
如果在除主线程之外的任何线程中进行一下操作,你就应该使用多线程版本的C runtime library,并使用_beginthreadex和_endthreadex:
(1) 使用malloc()和free(),或是new和delete
(2) 使用stdio.h或io.h里面声明的任何函数
(3) 使用浮点变量或浮点运算函数
(4) 调用任何一个使用了静态缓冲区的runtime函数,比如:asctime(),strtok()或rand()
2._beginthreadex和_beginthread区别
_beginthreadex内部会自动调用 _endthreadex.
_beginthread内部会自动调用_endthread.
_endthread内部会自动调用CloseHandle关闭当前Thread内核对象的句柄,所以在用_beginthread 时我们不需要在主线程中调用CloseHandle来关闭子线程的句柄。
_endthreadex相比_endthread而言更安全。它不会自动关闭当前Thread内核对象的句柄。所以在用_beginthreadex时我们需要用CloseHandle来关闭子线程的句柄。
5.伪句柄和真实句柄
1.伪句柄(Pseudohandle):
HANDLE GetCurrentProcess();
HANDLE GetCurrentThread();
以上两个函数会返回指向线程或进程内核对象的伪句柄(其实以上两个函数返回的是一个常数如-1)。所以伪句柄的值永远是指向当前线程或进程的。
如果把该值传给子进程,该值则代表当前子进程的伪句柄。所以把句柄传给子线程时一定要传真时的句柄不能传伪句柄。
该句柄不会增加内核对象的引用计数,所以不需要调用CloseHandle()函数。
2.把伪句柄转换成真实句柄
DuplicateHandle会增加内核对象的引用计数,所以要用CloseHandle()来关闭复制所得的对象句柄。
6.Common API
DWORD GetCurrentProcessId();
DWORD GetCurrentThreadId();
HANDLE GetCurrentProcess();
HANDLE GetCurrentThread();
DuplicateHandle()
线程基本概念
1.线程的组成
(1)线程内核对象:用于管理线程及存储线程的统计信息
(2)线程栈:维护线程执行时需要的函数参数和局部变量。 线程栈所需的内存是从进程中分配而得的,其大小默认是1M.
每个线程都有自已独立的线程栈。
进程不执行任何代码,所有的代码都是由线程执行的。进程相当于一个装载线程的容器。
线程共享进程的地址空间和数据,如内核对象句柄(内核对象句柄只能依附于某个进程而不是某个线程)
2.线程函数原型
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
DWORD dwResult = 0;
...
return(dwResult);
}
The system allocates memory out of the process' address space for use by the thread's stack.
3.终止线程
1.线程正常退出。系统会对线程函数内创建的所有对象调用析构函数。
2.ExitThread(). 线程退出, 系统会清理线程栈。 但是系统不会对线程函数内创建的所有对象调用析构函数。
3.TerminateThread().线程异步退出,系统不清理线程栈。只到拥有该线程的进程退出时才清理线程栈。
该函数是个异步函数,它只会告诉系统去杀掉某个线程,但是系统不会保证当该函数返回时线程立刻终止。
因此我们如果我们要确认线程已经终止了,则需要用WaitForSingleObject()来等待线程结束。
4.内核对象由进程所拥有,用户对象由线程拥有。线程可拥有两种用户对象:Windows和Hook.
5.线程终止后,线程所拥有的用户对象会被系统释放。
6.GetExitCodeThread() //检查线程是否已终止
4.线程内部细节
1.CreateThread 和 _beginthreadex 区别:
CreateThread是系统API,_beginthreadex是CRT(C Run Time Library 运行时库)函数. _beginthreadex内部会调用CreateThread函数。
_endthreadex会释放_beginthreadex为tiddata结构分配的内存。
如果线程函数中调用了CRT函数(注:不是全部CRT函数 只是其中一部分函数),则该线程函数必须由_beginthreadex而不是CreateThread函数创建。否则会产生内存泄露。
如果在除主线程之外的任何线程中进行一下操作,你就应该使用多线程版本的C runtime library,并使用_beginthreadex和_endthreadex:
(1) 使用malloc()和free(),或是new和delete
(2) 使用stdio.h或io.h里面声明的任何函数
(3) 使用浮点变量或浮点运算函数
(4) 调用任何一个使用了静态缓冲区的runtime函数,比如:asctime(),strtok()或rand()
2._beginthreadex和_beginthread区别
_beginthreadex内部会自动调用 _endthreadex.
_beginthread内部会自动调用_endthread.
_endthread内部会自动调用CloseHandle关闭当前Thread内核对象的句柄,所以在用_beginthread 时我们不需要在主线程中调用CloseHandle来关闭子线程的句柄。
_endthreadex相比_endthread而言更安全。它不会自动关闭当前Thread内核对象的句柄。所以在用_beginthreadex时我们需要用CloseHandle来关闭子线程的句柄。
5.伪句柄和真实句柄
1.伪句柄(Pseudohandle):
HANDLE GetCurrentProcess();
HANDLE GetCurrentThread();
以上两个函数会返回指向线程或进程内核对象的伪句柄(其实以上两个函数返回的是一个常数如-1)。所以伪句柄的值永远是指向当前线程或进程的。
如果把该值传给子进程,该值则代表当前子进程的伪句柄。所以把句柄传给子线程时一定要传真时的句柄不能传伪句柄。
该句柄不会增加内核对象的引用计数,所以不需要调用CloseHandle()函数。
2.把伪句柄转换成真实句柄
DuplicateHandle会增加内核对象的引用计数,所以要用CloseHandle()来关闭复制所得的对象句柄。
6.Common API
DWORD GetCurrentProcessId();
DWORD GetCurrentThreadId();
HANDLE GetCurrentProcess();
HANDLE GetCurrentThread();
DuplicateHandle()
发表评论
-
windows 常用网络查询命令(不断更新)
2012-12-05 11:12 606查询端口占用情况: netstat -aon|findstr ... -
[转]HTTP协议之Chunked解析
2012-11-27 14:53 974在网上找了好一会,始终没发现有解析Chunked编码的文章,那 ... -
[转] setsockopt :SO_LINGER 选项设置 socket error 10055
2012-11-10 12:53 1384setsockopt 设置 SO_LINGER 选 ... -
Nginx出现“413 Request Entity Too Large”错误解决方法
2012-11-05 13:59 997今天使用Wordpress的flash版文件上传功能的时候,总 ... -
【转】Netstat命令详解
2012-10-18 18:14 652Netstat用于显示与IP、TCP ... -
wireshark
2012-09-25 17:22 0frame.time >= "sep 25, ... -
【转】HTTP请求模型和头信息
2012-07-19 20:43 827HTTP请求模型 一、连接至Web服务器 一个客户端应用( ... -
查看网路连接的命令
2012-07-11 17:18 0netstat -ano | find "6003& ... -
服务器多服务器设置
2012-03-12 18:01 721当服务器功能比较多时,可以抽象出一个代理,将不同的服务 ... -
mongodb
2011-12-15 14:52 1597VS2010 将程序运行时库从MDD改为MTD(在MTD模式 ... -
mongodb 头文件包含问题
2011-12-15 10:02 1194添加 #include "dbclient.h&q ... -
Nginx 的介绍 (开源服务器)
2011-11-04 10:04 844http://blog.licess.org/nginx/ ... -
HTTP 协议 的简单解释
2011-11-01 20:32 724At a glance, HTTP is a fairly s ... -
windows 网络编程 函数
2011-05-06 16:48 843#include <winsock.h> u_ ... -
windows socket 编程资源
2011-05-05 07:21 701http://icourse.cuc.edu.cn/netwo ...
相关推荐
SocketError 错误代码查询SocketError 错误代码查询SocketError 错误代码查询
Socket编程中的Error捕获的中文解释,包括错误代码和中文释义
使用ftp时出现Socket ERROR的解决方法.docx
出现网络联机错误Socket error #11001 表示您的计算机无法连上服务器,请检查您的Proxy设定以及Proxy相关账号,或暂时取消您防毒软件的「个人防火墙」。 · 出现网络联机错误Socket error #11004 应该是网络...
VC套接字socket示例,在带接收函数recvfrom返回出错信息SOCKET_ERROR的时候可以自动自动启动重启机制。
socket详解 socket详解 socket详解 socket详解 socket详解 socket详解 socket详解 socket详解
总结JDBC连接SQLServer的错误Error establishing socket
windows socket错误码及出错原因,可以参考一下。也可MSDN。
SuperSocket写Socket客户端(连接,重连,接收处理数据)
if Result = SOCKET_ERROR then begin ErrorCode := WSAGetLastError; if ErrorCode <> WSAEWOULDBLOCK then begin Error(Self, eeReceive, ErrorCode); Disconnect(FSocket); if ErrorCode <> 0 then ...
Socket调制工具 Sockettool v4 支持TCP、UDP连接 exe可执行文件,解压后双击即可运行
SuperSocket 信息: (SpnRegister) : Error 1355。解决方法
// socket_read while show errors when the client is disconnected, so silence the error messages $data = @ socket_read ( $read_sock , 1024 , PHP_NORMAL_READ ); // check if the client is ...
if(SOCKET_ERROR == WSAGetLastError()) MessageBox(NULL, "Server recieve data failed!", "Error", MB_OK); printf("%s\n", recvBuf); char sendBuf[] = "Hello Server"; send(sockClient, sendBuf, sizeof...
socket.error: [Errno 98] Address already in use 这是因为在TCP/IP终止连接的四次握手中,当最后的ACK回复发出后,有个2MSL的时间等待,MSL指一个片段在网络中最大的存活时间,这个时间一般是30秒,所以基本上过60...
Cannot create TCP/IP socket(24).原因及解决办法
本文实例讲述了python使用socket远程连接错误处理方法。分享给大家供大家参考。具体如下: import socket, sys ... print Strange error creating socket: %s % e sys.exit(1) try: port = int(t
golang语言实现socket服务端,解决粘包拆包问题,心跳超时检测. //启动socket func (server *SocketServer) Start() { listener, err := net.Listen(server.Network, server.Address) if err != nil { server.On...
socket通讯,支持多线程通讯Socket communication, multi-threaded TCPIP communication, heartbeat maintenance, automatic reconnection, thread number configuration, etc. 报错 双语对照 Socket ...
=SOCKET_ERROR) { if (recvfrom(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&server,&len)!=SOCKET_ERROR) printf("rece from server:%s\n",buffer); } } closesocket(socket1); } BOOL ...