客户端可以将当代服务器与n对服务器连接起来。 一旦第一个成功,它必须向所有其他人发送信号,以关闭尝试连接的其余线程。 Shound我使用joinables线程来做到这一点?如果是,至少在概念上,我该如何进行?
感谢所有
答案 0 :(得分:3)
我们考虑请求n个资源的情况,并且获得的第一个资源取消所有其他请求。在您的特定情况下,资源是套接字连接。
如果可以异步请求资源(future/promise),那么必须有一个协议
定期检查检查请求的状态(轮询),或者接收该请求的完成(处理程序)通知,并
可能取消请求
在该模型中,您只需要一个线程来启动所有请求并轮询/等待通知。获取一个或多个资源后,选择其中一个,关闭其他资源,并取消所有剩余的需求(如果无法取消,只需在通知时释放每个额外资源,或专用额外线程对其进行轮询并发布收到时。)
如果资源请求命令是同步的(阻塞套接字connect
调用),则确实需要n
个并发线程,每个线程都调用阻塞函数。在返回时,每个人都应该检查一个标志,指示另一个线程是否先获得了他的资源。如果不是这种情况,则线程定位标志并继续。否则,线程释放资源。
标志必须是原子的,或者是互斥保护的。
作为一个类比,想象一下n个参赛者之间的比赛:他们都是一个接一个地开始,并且他们必须抓住一个标志才能继续。为了做到这一点,他们必须进入一个房间,一次只允许1个人(互斥体),但首先他们必须得到一个号码(连接到服务器)。一旦参赛者成功拿到一个号码,她就会走到门前,试着进入房间(拿着互斥锁)。如果没有人在里面,她会进入(或等到房间空了),并检查标志是否仍在那里(flag == 0
)。如果是,她接受它(flag = 1;
),然后继续。否则,她必须退还她的号码并退出比赛(关闭连接和退出)。
线程任务基本如下:
void task(address){
int socket = connect(address);
If (!check_flag()){
proceed(socket);
} else {
close(socket);
}
}
其中proceed
是套接字的剩余工作。
check_flag
功能解释如下。
使用 pthreads ,您需要pthread_mutex
来实现它。如果机器memory model允许,您也可以使用简单的volatile
整数,但它显然不可移植。
从根本上说,只需要一个函数来处理标志。伪代码看起来像这样:
int flag;
int check_flag(){
int result=0;
lock();
result = flag;
flag = 1;
unlock();
return result;
}
返回标志是否已设置,并设置它。
我应该补充一点c11为atomic variables提供可选支持。请参阅OS C编译器文档。