通讯库多线程问题

开始远离编程 2005-08-15 10:59:48
最近,用完成端口实现了一个通讯库。这是一个动态库,导出一个类似CAsyncSocket对象,
这样一个对象将绑定一个socket。由于是用完成端口模型实现的,因此导出的对象的肯定
会被通讯库中多个线程调用,也就是存在跨线程调用的问题。我想这样的实现方式在
应用程序中使用时可能会导致跨线程调用引起的错误,给应用程序的使用带来很多致命限制。
之前,已经用CAsyncSocket实现了一个相同接口的通讯库。这个通讯库主要完成打包、压缩流量统计、访问控制等功能。这次实现的通讯库,采用了相同的接口,性能倒是有了大幅度的提高,不过总感觉存在隐患。希望各位大虾发表一下意见,具体可能会出现哪些问题?有什么解决方法?还有一般通讯库设计一般有什么需要注意的地方?
...全文
200 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
DentistryDoctor 2005-08-16
  • 打赏
  • 举报
回复
CAsyncSocket本身不是线程安全的,主要原因是因为其在SOCKETG与CAsyncSocket之间建立的map。你的类封装SOCKET就行了,不要那个map了。
mymyal123 2005-08-16
  • 打赏
  • 举报
回复
新人,学习
开始远离编程 2005-08-16
  • 打赏
  • 举报
回复
bilujun(编程低手) 和 txl_2002(菜鸟) 说的和我想的差不多。
不过如果将这些回调函数同步性能可能有较大影响。
我想知道一般编写通讯库的时候,是采用哪种方式的,同步还是不同步
这些回调函数。
至于Send、Receive之类用户主动调用的函数,一般都是由用户自己
作互斥保护的。
softrain 2005-08-16
  • 打赏
  • 举报
回复
不要在回调函数外使用临界区之类的同步方法,这对性能的影响太大了。
由用户在回调函数中决定什么时候开始同步,什么时候结束。因为你的类库是封装通讯,而不是应用。
txl_2002 2005-08-15
  • 打赏
  • 举报
回复
bilujun(编程低手)
讲的东东和完成端口无关啊。
其实楼主的意思是OnSend和OnReceive可能会同时被回调,会让通讯库上层的编程有麻烦,如果在通讯库里处理了同步问题,又怕性能受影响。
其实这也没办法的,性能和安全总是要有代价的,看你需要什么了。建议搂住在通讯库就做好安全工作。
  • 打赏
  • 举报
回复
如果是使用多线程的话你的类的每个接口函数都可能被多个线程同时调用,如果每个线程都是使用单独的类的实例可能没有问题,如果是一个实例在多个线程中使用,则这些接口函数要做好互斥,使用临界区之类的控制数据的并发访问。

比如,class中有一块缓冲区,多个线程通过class的read和write接口访问这块缓冲区,就需要对访问进行并发控制
开始远离编程 2005-08-15
  • 打赏
  • 举报
回复
主要问题就是导出的类似CAsyncSocket对象CMySocket,里面的那些回调函数,如OnReceive、OnSend、
OnConnect等函数,目前的实现方式直接在完成端口的工作线程中调用,每次负责调用的线程可能是工作线程中的任意一个。因此这个对象存在跨线程调用的问题。目前的想采用解决方案是将这些对象与通讯库特定的一个工作线程绑定到一起。
bilujun 2005-08-15
  • 打赏
  • 举报
回复
初始化时候创建事件指初始化时候创建事件内核对象。
bilujun 2005-08-15
  • 打赏
  • 举报
回复
下面是我的想法,可能不一定对
1.在通讯库的工作线程中同步onReceive.
初始化时候创建事件
DWORD WINAPI WorkThread(LPVOID lparam)
{
...
//等待事件
WaitForSingleObject(hEvent, INFINITE);
//回调函数
OnReceive(lpHandleData->Socket,lpIoData->DataBuf,dwByteTransferred);
// 处理完成后即将事件对象置位
  SetEvent(hEvent);
...
}
这样缺点效率有下降,因为多个工作线程并行处理,但必须一个一个的串行处理onReceive回调函数。
好处是通讯库自己保证回调函数是线程安全的
2.调用者自己处理线程同步,这也很正常啊,如java的HashMap不提供线程安全,而HashTable提供线程安全。不提供线程安全的好处就是可以用更合理的同步方式来达到最高效率
VCSQLVB 2005-08-15
  • 打赏
  • 举报
回复
如果客户在多个线程里访问你的同一个库就会引起互斥访问问题,所以应该把库里的变量(可能被同时访问的)放入临界区里。
开始远离编程 2005-08-15
  • 打赏
  • 举报
回复
to 回复人: orbit(走了走了) ( ) 信誉:111
====================
这里我把程序分成应用程序和通讯库两部分。
通讯库导出的类,一般要求在应用程序中一个线程中使用。
如果应用程序中要在不同线程中使用,需要应用程序自己做互斥,
这个不会有什么问题。
但是对于类中的OnReceive、OnSend函数是由通讯库中完成端口工作线程回调的,
而且这两个函数可能在完成端口的两个工作线程同时被调用。
因此在应用程序中使用这个类时,可能会出现问题。

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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