gpt4 book ai didi

c - AF_UNIX 套接字 : select() firing when there is nothing to read

转载 作者:行者123 更新时间:2023-11-30 18:38:29 25 4
gpt4 key购买 nike

该程序创建 n 个线程来模拟分布式系统中的 n 个节点,每个线程都有一个监听的套接字,并且每个线程可以通过 connect 调用与 n-1 个其他线程进行通信。

  1. 每个线程都会调用 select() 以查看是否有可用的内容,如果有则接受并保存数据。

  2. 我使用带有标志 FIONREAD 的 ioctl 来检查可读取的字节数并执行适当的读取调用。之后新的 fd(来自accept())被关闭。

  3. 监听套接字正在阻塞。 O_NONBLOCK 未设置。

  4. 所有 n 个线程都运行相同的函数。函数内声明的所有变量都使用线程本地存储。

  5. 我没有进行显式同步。多个线程可以同时尝试连接到同一个套接字。

现在的问题是,偶尔,接收端线程中的 select() 会记录一些新内容,但可用字节数为 0,而这不应该是 0。这种情况的发生不一致。

如果有人能指出我应该调查的地方,那就太好了。谢谢!

创建 socks

  if ( (nptr->sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
fd_max = nptr->sock > fd_max ? nptr->sock : fd_max;

int ok=1;
setsockopt(nptr->sock, SOL_SOCKET, SO_REUSEADDR, &ok, sizeof(int));

nptr->addr.sun_family = AF_UNIX;
snprintf(nptr->addr.sun_path, 20, "%d", nptr->id);
//strncpy(nptr->addr.sun_path, sock_path, 20);

if ( bind(nptr->sock, (struct sockaddr*)&(nptr->addr), sizeof(struct sockaddr_un)) < 0 ) {
perror("bind");
exit(1);
}
/* socket, max connections */
if ( listen(nptr->sock, 2*tot_node) < 0 ) {
perror("listen");
exit(1);
}

发送东西

for (t=0; t<tot_node; t++) {
...

if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}

printf("Node %d: trying to req node %d... ", self->id, node_catalog[t]->id);
if ( connect(fd, (struct sockaddr*)&(node_catalog[t]->addr), sizeof(struct sockaddr_un)) == -1 ) {
perror("connect");
exit(1);
}

buf[0] = TYPE_REQ;
buf[1] = self->id;
buf[2] = ts;
buf[3] = rsc;

write (fd, buf, 4*sizeof(int));

//close(fd);

printf("Node %d: sent req for resource %d to %d\n", self->id, rsc, node_catalog[t]->id);
}
usleep(TS_UPDATE_ITV);

收到东西

    FD_ZERO(&readset);
FD_SET(self->sock, &readset);
t = pselect(self->sock+1, &readset, NULL, NULL, &tout, NULL);
if (t > 0 && FD_ISSET(self->sock, &readset)) {

com_fd = accept(self->sock, NULL, NULL);

ioctl(com_fd, FIONREAD, &t);
#ifdef DEBUG
printf(" Node %d: received %d bytes of data\n", self->id, t);
#endif

read(com_fd, buf, t);
close(com_fd);

dptr = (int *)buf;
rsc = t / (sizeof(int)); /* var reuse. this is the count of ints to read */

for (t=0; t<rsc; ) {
static __thread int nid, nts, nrsc;
#ifdef DEBUG
printf(" Node %d: data rcvd: %d %d %d %d", self->id, *dptr, *(dptr+1), *(dptr+2), *(dptr+3));
#endif

if (*dptr == TYPE_REQ) {
... } else {...}

最佳答案

你的代码没有意义。原因是select()被解雇是因为有一些事情需要接受。在刚刚接受的套接字上检查 FIONREAD 可能会或可能不会导致数据可用。这完全取决于客户是否已发送。不在select()的契约(Contract)上.

如果你需要知道是否有东西可读,你应该将接受的套接字添加到read-FD集合中,并循环处理:如果监听套接字可读,则调用accept()上,否则它是一个接受的套接字,您应该调用 read()就在上面。

在大多数情况下,检查 FIONREAD 实际上只是浪费时间。

关于c - AF_UNIX 套接字 : select() firing when there is nothing to read,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33844338/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com