【发布时间】:2014-05-21 13:32:35
【问题描述】:
对于一个学校项目,我们将使用文件描述符和 select() 在一台机器上实现并发。在程序中,我们有 RequestChannel 对象,其中包含两个文件描述符,一个用于读取,一个用于写入,用于与在执行开始时分叉的单独进程进行通信。我可以用写文件描述符来做一些事情,但读 fds 似乎永远不会准备好。我能否获得一些帮助来理解 select() 如何与读写描述符一起工作?我看到的一切都是在处理套接字,这让我很困惑,我只想了解通用文件描述符和 select()。
这是我的选择循环:
fd_set readset, writeset;
FD_ZERO(&readset);
FD_SET(JohnDoe.read_fd(), &readset);
FD_SET(JoeSmith.read_fd(), &readset);
FD_SET(JaneSmith.read_fd(), &readset);
FD_ZERO(&writeset);
FD_SET(JohnDoe.write_fd(), &writeset);
FD_SET(JoeSmith.write_fd(), &writeset);
FD_SET(JaneSmith.write_fd(), &writeset);
int maxfd = 0;
maxfd = max(maxfd, JohnDoe.read_fd());
maxfd = max(maxfd, JohnDoe.write_fd());
maxfd = max(maxfd, JoeSmith.read_fd());
maxfd = max(maxfd, JoeSmith.write_fd());
maxfd = max(maxfd, JaneSmith.read_fd());
maxfd = max(maxfd, JaneSmith.write_fd());
int numready;
int count = 0;
while (count < 10) {
numready = select(maxfd + 1, &readset, &writeset, NULL, NULL);
if (numready == -1) {
cout << "Fatal error, aborting\n";
break;
}
else {
if(FD_ISSET(JohnDoe.write_fd(), &writeset)) { //write_fd() returns write file descriptor
JohnDoe.cwrite("data John Doe"); //one RequestChannel object
}
if(FD_ISSET(JoeSmith.write_fd(), &writeset)) {
JoeSmith.cwrite("data Joe Smith");
}
if(FD_ISSET(JaneSmith.write_fd(), &writeset)) {
JaneSmith.cwrite("data JaneSmith");
}
if(FD_ISSET(JohnDoe.read_fd(), &readset)) {
string s = JohnDoe.cread();
cout << "John Doe cread: " << s << "\n";
}
if(FD_ISSET(JoeSmith.read_fd(), &readset)) {
string s = JoeSmith.cread();
cout << "Joe Smith cread: " << s << "\n";
}
if(FD_ISSET(JaneSmith.read_fd(), &readset)) {
string s = JaneSmith.cread();
cout << "Jane Smith cread: " << s << "\n";
}
}
}
【问题讨论】:
-
我没有看到为
select()调用设置描述符集的代码。应该有一些FD_ZERO()和FD_SET()调用来初始化描述符集。 -
我之前只是显示了选择循环,但我添加了它
标签: c++ c select system-calls