请教:不同线程间如何操作同一个Socket?

sayno 2003-07-09 05:54:10
诸位老大:
我有一个Socket链接(主线程中一个CSocket对象),需要在另一个独立的线程中关闭(或重新连接),但在线程中总是异常(向外发送是正常的,Close和Connect异常),请教了一位老大,他说线程中的映射表是独立的,找不到另一个线程中的Socket句柄和window句柄,但如果我在子线程中创建该CSocket对象,在主线程中又无法操作,请教诸位,这个问题应如何解决?以下是示例代码:

...
CSocket sockTest;
UINT SockClose(LPVOID lParam); //链接维护
void CTestDlg::OnSocktest()
{
if(sockTest.Create()!=0)
{
if(sockTest.Connect("xxx.xxx.xxx.xxx",5000))
Sleep(10);
}

AfxBeginThread(SockClose,(LPVOID)NULL);
}
UINT SockClose(LPVOID lParam)
{
Sleep(1000) ;
sockTest.Close();
}
...全文
253 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
sayno 2003-08-06
  • 打赏
  • 举报
回复
抱歉,出差了一个月,回来看到这里这么热闹,mmns和ilovevc的争论使在下受益非浅,多谢诸位的帮助。
lsw0794 2003-08-03
  • 打赏
  • 举报
回复
学习
wglacier 2003-07-28
  • 打赏
  • 举报
回复
纠正一下,不是CWnd的问题,是CSocketWnd!sockcore.cpp里写的很清楚
mct1025 2003-07-24
  • 打赏
  • 举报
回复
CSocket类,不能跨线程访问
CAsyncSocket类,Socket API 都可以
smallfool 2003-07-24
  • 打赏
  • 举报
回复
昏倒。线程间共享CWnd指针和楼主的问题似乎有点差异的吧。两人的火气怎么都这么大啊?
不过针对楼主的问题,你不妨可以传递SOCKET句柄试试看

这里还有这是线程回调函数。是有区别的。
chijiao 2003-07-24
  • 打赏
  • 举报
回复
关注。
WalkWorld 2003-07-24
  • 打赏
  • 举报
回复
虚心学习
ilovevc 2003-07-15
  • 打赏
  • 举报
回复
线程之间共享CWnd的指针在某些情况下是可以的, 但是, 我是就楼主这
个具体的问题,提出为什么CSocket不能被多线程使用的原因是由于内部隐藏的
CWnd在这种情况下不能被多线程使用.

例如,如果CWnd定义了一个成员变量int m_abc, 你需要传递这个CWnd指针到另外
一个线程中来接收m_abc, 毫无疑问, 你在线程函数中使用 pWnd->m_abc确实
没有问题.这个时候, 你没有使用CWnd的特性, 只是将pWnd当做一个普通的
class来处理.

甚至, 你使用pWnd->SetWindowText也没有问题, 因为这个函数内部实际
上是调用一个SDK函数 { ::SendMessage(m_hWnd, WM_SETTEXT....}
都没有涉及到我提到的这个map.

但是,某些情况下, 例如楼主说的CSocket, 这时pWnd就无法跨线程使用了.
因为CSocket某些函数在内部涉及到这个map.而这个map是线程独立的.

MSDN既然提到了最好不要在线程之间传递CWnd,必定有它的道理,那么肯定
有些情况是不能传递CWnd的, 你只是没有遇到这种情况而已.


rujor 2003-07-15
  • 打赏
  • 举报
回复
mark,喂,高手们,不要吵架啊,讲问题先。
神农氏 2003-07-15
  • 打赏
  • 举报
回复
再多说一句;
你的火气也不小啊,
mfc的主要历史如下
mfc 1.0 1992 这个版本基本没价值
mfc 2.5 1993年12月
mfc 4.0 1995年12月
mfc 4.2 1997年3月19日
用mfc超过8年了! 是95年7月15日以前吗? 那时用MFC的人可是少的可怜啊(都是用API),而且那时编写的程序也大多是WIN3.1的(不才在96年写过几天),像你这样的元老级人物现在不多见了,呵呵!
咱们倒是可以交个朋友。


神农氏 2003-07-15
  • 打赏
  • 举报
回复
你说的很对,在msdn的文档中,是说最好不要在线程之间传递窗口指针,而是要传递窗口句柄,我一开始也是这样做的,但是用句柄就只能通过消息通讯,很麻烦,实际情况是,在线程之间使用cwnd指针从来没有出过问题。
CWnd 到hwnd是有映射,那又怎么样呢,难道就说明线程之间不能共享cwnd对象吗! 我还是那句话,我劝你还是写个程序试试吧!
双杯献酒 2003-07-15
  • 打赏
  • 举报
回复
UP
ilovevc 2003-07-15
  • 打赏
  • 举报
回复
to mmns:
不客气, 大家相互学习.呵呵
刚刚看到你的前一个帖子, 呵呵, 不好意思, 我说的8年只是虚构,
是为了回应你的"开8个线程". 实际上我没有使用MFC这么长时间,当然,
也是为了让你不至于先入为主,认为我完全是"胡搅蛮缠".

不过, 学习MFC也确实有点年头了, 从97年开始. 不过最近就很少用了.
神农氏 2003-07-15
  • 打赏
  • 举报
回复
to : ilovevc(ilovevc)
今天我专门跟了一下,你说的是对的。有些情况确实会出问题。
很对不起,以前犯了经验主义的错误,以后向你学习
ilovevc 2003-07-14
  • 打赏
  • 举报
回复
to mmns:
火气不要这么大.

>>我在线程之间传递窗口指针,不是为了共享是为了干什么!
再说一次, 在多线程程序中传递CWnd对象是危险的.
你可以在你的任何一个线程函数中测试以下代码:
DWORD WINAPI ThreadProc(LPVOID aArg)
{
CWnd * pWnd = (CWnd *)aArg;
pWnd->AssertValid();
}

在Debug版本中的 pWnd->AssertValid();会弹出"Debug Assertion Failed",
然后你跟踪进入MFC的源代码, 下面的MFC源代码的注释:

// Note: if either of the above asserts fire and you are
// writing a multithreaded application, it is likely that
// you have passed a C++ object from one thread to another
// and have used that object in a way that was not intended.
// (only simple inline wrapper functions should be used)
//
// In general, CWnd objects should be passed by HWND from
// one thread to another. The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
//
// It is dangerous to pass C++ objects from one thread to
// another, unless the objects are designed to be used in
// such a manner.

api和mfc我都用了好几年了,难道GetMessage(.....)是干啥的还不知道。
我劝你还是写个程序试试吧!
>>我使用MFC超过8年时间了.按年头,也不比你少. 不过,我在学MFC的第
2年就知道MFC内部有一个HWND<->CWnd的映射了.

GetMessage你是知道, 但是, 你必定不知道MFC是如何将GetMessage中
得到的消息映射到CWnd对象的成员函数,否则,你也不至于不理解我说的
意思了.

例如, GetMessage( LPMSG lpMsg, HWND hWnd,
UINT wMsgFilterMin, UINT wMsgFilterMax )函数, LPMSG结构中
只有一个HWND变量,并没有CWnd*的指针, 那么收到这个消息以后,
MFC是如何知道调用哪个CWnd对象的成员函数?也就是MFC如何
知道从一个HWND->CWnd? 所以,我说需要一个HWND->CWnd*的映射.

当然, CWnd->HWND就太简单了, 既然Cwnd包含有一个HWND的成员变量.
mldds 2003-07-14
  • 打赏
  • 举报
回复
一个线程(关闭线程)关闭另一个线程(被关闭线程)的通常做法应该是;
设一个共享的CEvent
关闭线程是调用CEvent的SetEvent
被关闭线程的主循环中调用WaitFor*系列函数等待此CEvent事件,等到此事件则主动退出
关闭线程调用WaitForSingleObject(被关闭线程的句柄, 等待超时时间),确认被关闭线程退出

神农氏 2003-07-14
  • 打赏
  • 举报
回复
ilovevc(ilovevc)
我在线程之间传递窗口指针,不是为了共享是为了干什么!
api和mfc我都用了好几年了,难道GetMessage(.....)是干啥的还不知道。
我劝你还是写个程序试试吧!开8个线程同时操作一个窗口指针没有问题
danielzhu 2003-07-14
  • 打赏
  • 举报
回复
学习
jvcit 2003-07-14
  • 打赏
  • 举报
回复
关注!!
sayno 2003-07-14
  • 打赏
  • 举报
回复
还有一个问题:
我按Detach()...Attch()方式,虽然解决了问题,但在编译release 版本时如果使用 “Use MFC in a static Library” 方式,则程序在Attch()时会出现异常,而如果动态使用MFC 库则一切正常,请问这个问题应如何解决?
加载更多回复(11)
概述:宠物智能饲养监测系统基于RT-Thread的ART-PI开发板,主控STM32F750XBH6,支持采集温度、湿度和光照数据,实现高温本地和远程预警,智能照明控制,实时采集数据并通过 WIFI 上传云端,针对智能宠物管理提供一个较好的使用范例,也是自己借参加本次活动,首次实操使用RT-Thread rtos,实现功能是次要目的,学习和使用rtt是初衷,之后本项目会继续增加新功能,简单来说这是一个比较实用的。 开发环境硬件:ART-PI 扩展板:DHT11温湿度传感器,BH1750光照传感器和灯控模块 RT-Thread版本:RT-Thread V 4.0.3 开发工具及版本:RT-Thread-studio v2.0.0,STM32CubeMX v6.1.0 RT-Thread使用情况概述内核部分:调度器。 调度器:创建多个线程来实现不同的工作。 组件部分:I2C框架, Sensor框架, SAL 套接字抽象层 I2C框架:使用I2C框架来驱动光照传感器,上层代码可以提高代码的可重用性。 Sensor框架:为上层提供统一的操作接口,提高上层代码的可重用性;简化底层驱动开发的难度,可以非常简单的读取传感器采集数值。 SAL 套接字抽象层:组件完成对不同网络协议栈或网络实现接口的抽象并对上层提供一组标准的 BSD Socket API,这样开发者只需要关心和使用网络应用层提供的网络接口,而无需关心底层具体网络协议栈类型和实现,极大的提高了系统的兼容性,方便开发者完成协议栈的适配和网络相关的开发 软件包部分: Webclient: 提供设备与 HTTP Server 的通讯的基本功能,主要使用http post。 BH1750FVI: 该传感器软件包提供了使用光照强度传感器基本功能,BH1750FVI 是一种用于两线式串行总线接口的数字型光强度传感器集成电路,具有较高的分辨率可以探测较大范围的光强度变化(范围: 1lx-65535lx),特别适合对光照环境要求较高的场景。 硬件框架ART-PI采集到数据上传到云端(目前使用自己php+mysql,断网本地存储测试中)。 软件框架说明上电初始话后,检测传感器变化,满足设定条件的,通过wifi上传到服务器端 目前服务器端只提供数据处理和存储 软件模块说明bh1750_thread_entry: 光照传感器线程 dht11_thread_entry:温湿度传感器线程 user_webclient_post:http_post main:led 闪烁,用来检测当前系统的运行状态。 演示效果视频演示比赛感悟首先非常感谢RTT和电路城以及ST等一起举办的这次活动。 由于第一次使用M7核mcu以及第一次使用rtt操作系统,从小白一步一步学习,测试,看文档,请教,虽然目前还是小白水平,但是确确实实是一次难得的机会,不亲自实践就永远不知道自己的水平在哪,也不能了解rtt便捷。不得不说,结束rtt studio之后,使用起来非常顺手,再者H750 480MHz搭配art-pi强悍的设计,用于之后的复杂功能开发测试有巨大的升级空。 这次比赛不仅仅是学到了,rtt stm32的软硬件知识,更多的是和许多志同道合的小伙伴,讨论与分享自己的所获所得,这也是一种开源精神。 最后要说声抱歉,鉴于没有充分认识到自己有限的水平,虽然近一个月的时,还只能写出这样的水平,心比天高无奈水平一般,但是这是一个开始,会围绕设计主题,做持续的更新,不断学习和实践,继续让art-pi发光发热。 感谢!!!

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧