我现在卡在设计/逻辑舞台上。我有一个运行2个线程的客户端,并使用1个连接到服务器的套接字。
在主线程中有GUI操作,当用户在程序标题栏上单击X时,程序将CLOSE数据包发送到服务器,服务器从用户列表中删除cleint - 这没有问题。
当我添加了允许运行服务器的人手动从服务器中删除用户的选项时出现了问题。当管理员右键单击用户时,他可以踢他 - >然后服务器发送CLOSE数据包到客户端,这是有效的,但这里是捕获:
客户端使用我说的一个线程中的2个线程,他发送CLOSE数据包,而在另一个线程中,他在不同的线程中等待它(阻塞) - 该线程甚至在显示窗口之前启动。
所以我们这里有问题:
客户端加入服务器并想离开它 - 不会工作,因为客户端的第二个线程已经阻塞了套接字,第一个线程无法发送CLOSE数据包。
任何想法如何解决它?
编辑:现在我不确定它是否有问题,因为有时它有效,有时第一个线程不发送数据或服务器无法恢复。
无论如何我还刚刚读到recv并从不同的线程发送一个套接字应该不是问题所以我很困惑。
答案 0 :(得分:0)
吸引read()
或write()
或pselect
等阻止的pthread注意力的一种方法是pthread_kill(),它会向特定的pthread传递信号。必须设置目标pthread以捕获您选择的“唤醒”信号(空信号处理程序将执行此操作)并且不屏蔽它。
然而,这里有一个很大的问题......你无法判断pthread是否被阻止,也无法判断它是否即将被阻止,因此信号可能会丢失!所以,接下来的技巧是使用非阻塞I / O和pselect()
- 这似乎确实打败了让pthread远离所有这一切的目的!现在你要做的是在pthread中大部分时间掩盖“唤醒”信号。但是,当pthread在pselect()
上“进入睡眠状态”时,您可以设置pselect以在等待时取消屏蔽“唤醒”信号。这可以安排可靠地传递信号。当pselect返回时,您必须检查错误,尤其是EINTR
。
使用pselect()
,您还可以设置虚拟管道,您也可以等待。为了吸引pthread的注意,你写信给管道。我碰巧更喜欢信号方法。