加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

当线程A关闭套接字对的末尾时,为什么windows select()并不总是通

发布时间:2020-12-14 02:18:36 所属栏目:Windows 来源:网络整理
导读:我在 Windows XP(SP3)下遇到的情况让我疯狂,而且我已经到了我的系绳的末端,所以也许有人可以提供一些灵感. 我有一个C网络程序(非GUI).该程序用于在Windows,MacOS / X和Linux下编译和运行,因此它使用select()和非阻塞I / O作为其事件循环的基础. 除了网络功能
我在 Windows XP(SP3)下遇到的情况让我疯狂,而且我已经到了我的系绳的末端,所以也许有人可以提供一些灵感.

我有一个C网络程序(非GUI).该程序用于在Windows,MacOS / X和Linux下编译和运行,因此它使用select()和非阻塞I / O作为其事件循环的基础.

除了网络功能外,该程序还需要从stdin读取文本命令,并在stdin关闭时正常退出.在Linux和MacOS / X下,这很容易 – 我只是在我的read fd_set中包含STDIN_FILENO来select(),而select()在stdin关闭时返回.我检查FD_ISSET(STDIN_FILENO,& readSet)是否为真,尝试从stdin读取一些数据,recv()返回0 / EOF,所以我退出进程.

另一方面,在Windows下,您无法选择STDIN_FILE_HANDLE,因为它不是真正的套接字.您也不能对STDIN_FILE_HANDLE执行非阻塞读取.这意味着无法从主线程读取stdin,因为ReadFile()可能无限期地阻塞,导致主线程停止提供其网络功能.

没问题,我说,我只会产生一个线程来处理stdin.该线程将在无限循环中运行,在ReadFile(stdinHandle)中阻塞,并且只要ReadFile()返回数据,stdin线程就会将该数据写入TCP套接字.该套接字的另一端将由主线程选择(),因此主线程将看到通过连接进入的stdin数据,并以与其他任何操作系统相同的方式处理“stdin”.如果ReadFile()返回false以指示stdin已关闭,则stdin-thread仅关闭其套接字对的结尾,以便主线程将通过select()通知,如上所述.

当然,Windows没有一个很好的socketpair()函数,所以我不得不使用listen(),connect()和accept()(如CreateConnectedSocketPair()函数here中所见.)但我做到了一般而言,它似乎有效.

问题是它不能100%工作.特别是,如果stdin在程序启动的几百毫秒内关闭,大约一半时间主线程没有得到任何关于套接字对的stdin-end已经关闭的通知.我的意思是,我可以看到(通过我的printf() – 调试)stdin线程在其套接字上调用closesocket(),我可以看到主线程是select() – 关联socket(即套接字对的另一端),但是select()永远不会返回……如果它确实返回,由于某些其他套接字选择了ready-for-whatever,FD_ISSET(main_thread_socket_for_socket_pair,& readSet) )返回0,好像连接没有关闭.

在这一点上,我唯一的假设是Windows的select()实现中存在一个错误,导致主线程的select()没有注意到套接字对的另一端已被stdin-thread关闭.有另一种解释吗? (请注意,此问题已在Windows 7下报告,尽管我没有在该平台上亲自查看过它)

解决方法

仅仅为了记录,这个问题完全是一个完全不同的问题,与线程,Windows或stdin无关.实际问题是进程间死锁,其中父进程被阻塞,等待子进程退出,但有时子进程会被同时阻塞,等待父进程为它们提供一些数据,所以什么都不会前进.

向所有人道歉,浪费你的时间在红鲱鱼身上;如果有一种标准方法可以将这种情况视为无根据,请告诉我,我会这样做.

-Jeremy

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读