首页 \ 问答 \ 如何在epoll_wait之后更新epoll事件?(How to update epoll events after epoll_wait?)

如何在epoll_wait之后更新epoll事件?(How to update epoll events after epoll_wait?)

我有以下代码摘录(经过严格修改以删除不重要的细节),这些代码在罕见且特殊情况下失败。

struct epoll_event *events = calloc(MAXEVENTS+1, sizeof(struct epoll_event));
struct sockaddr_in in_addr;
socklen_t in_len = sizeof in_addr;

while(1)
  {
  int n = epoll_wait(efd,events, MAXEVENTS, -1);
  for(int i=0; i<n; i++)
    {
    struct epoll_event *evI = &events[i];
    uint64 u64 = evI->data.u64;
    int type = u64>>32, fd=u64, fdx = fd;

    if(type == -1)
      {
      while((fd = accept4(fdx, &in_addr, &in_len, SOCK_NONBLOCK|SOCK_CLOEXEC))>-1)
        {
        setNew_Connection(efd, fd);
        storeAddrPort(fd, &in_addr, &in_len);
        }
      }
    else
      {
      if(evI->events&(EPOLLERR|EPOLLHUP|EPOLLRDHUP)){closeConnection(fd);}
      if(evI->events&EPOLLOUT)  //process out data stuff
      else if(evI->events&EPOLLIN) //process in data stuff and possibly close a different connection.
      }
    }
  }

侦听套接字在evI->data.u64的上半部分用-1evI->data.u64

setNew_Connection通常接受像添加epoll等新套接字的东西

EPOLLET

现在一切都运行得非常好,除非在以下情况下它失败,因为events只在epoll_wait更新,所以连接闭包不会影响n事件,直到返回到while(1)循环的顶部。

  1. epoll_wait用在事件结构表中排队的3个事件epoll_wait
  2. 第一个事件(n = 0)是在代码决定关闭连接(例如文件描述符8)之后的传入数据,因为它不再需要。
  3. 第二个事件(n = 1)是传入的新连接。 accept4指定最近可用的fd:8。 setNew_Connection将其添加到epoll列表中。
  4. 第三个事件是在步骤2中关闭的连接的输入数据,即fd:8,但由于原始fd:8连接已关闭且当前fd:8用于不同连接,因此它不再有效。

我希望我已经充分解释了这个问题。 问题是,在关闭连接之前, events表中的排队事件不会更新,直到代码返回到epoll_wait 。 我怎么能解决这个问题呢?


I have the following code excerpt (heavily redacted to remove unimportant details) which fails under a rare and particular set of circumstances.

struct epoll_event *events = calloc(MAXEVENTS+1, sizeof(struct epoll_event));
struct sockaddr_in in_addr;
socklen_t in_len = sizeof in_addr;

while(1)
  {
  int n = epoll_wait(efd,events, MAXEVENTS, -1);
  for(int i=0; i<n; i++)
    {
    struct epoll_event *evI = &events[i];
    uint64 u64 = evI->data.u64;
    int type = u64>>32, fd=u64, fdx = fd;

    if(type == -1)
      {
      while((fd = accept4(fdx, &in_addr, &in_len, SOCK_NONBLOCK|SOCK_CLOEXEC))>-1)
        {
        setNew_Connection(efd, fd);
        storeAddrPort(fd, &in_addr, &in_len);
        }
      }
    else
      {
      if(evI->events&(EPOLLERR|EPOLLHUP|EPOLLRDHUP)){closeConnection(fd);}
      if(evI->events&EPOLLOUT)  //process out data stuff
      else if(evI->events&EPOLLIN) //process in data stuff and possibly close a different connection.
      }
    }
  }

Listening sockets are differentiated by -1 in the upper part of evI->data.u64

setNew_Connection does the usual accepting stuff like adding the new socket to epoll etc

EPOLLET is used.

Now it all works brilliantly except under the following circumstances it fails because events is only updated in the epoll_wait so a connection closure does not affect the n events until after returning to the top of the while(1) loop.

  1. epoll_wait unblocks with 3 events queued in the events struct table.
  2. First event (n=0), is incoming data after which code decides to close a connection (e.g. file descriptor 8) as it is no longer needed.
  3. 2nd event (n=1) is an incoming new connection. accept4 assigns fd:8 as it has recently become available. setNew_Connection adds it to the epoll list.
  4. 3rd event is incoming data for the connection closed in step 2. i.e. fd:8 but it is no longer valid as the original fd:8 connection was closed and the current fd:8 is for a different connection.

I hope I have explained the problem adequately. The issue is that queued events in the events table are not updated when a connection is closed until the code returns to epoll_wait. How can I code around this problem?


原文:https://stackoverflow.com/questions/33382000
更新时间:2023-07-12 12:07

最满意答案

如果您在滚动时UI很崎岖,它只是意味着您在collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell执行的操作collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell太重了。

Realm本身的结构是这样一种方式,即从对象读取数据的速度非常快,所以如果您所做的只是使用Realm中的值填充单元格, 则不应该看到大量丢帧。

几个注意事项:

  • 如果你在cellForItem块方法中调用item.children ,因为你手动循环并在每个Realm对象中进行分页,这将导致帧丢失。 如果你是,那么最好提前做到这一点,或者重新设计逻辑只在绝对需要的时候访问那些数组。
  • 你提到你包括图像。 即使图像在磁盘上,除非你提前强制图像解压缩,否则Core Animation会在主线程上的绘图时间懒惰地解压缩图像,这会严重影响滚动性能。 有关详细信息,请参阅此问题
  • cellForItemAt方法调用应该已经在主线程上,因此在DispatchQueue.main.async闭包中配置您的单元似乎是不必要的,并且假设它不是同步的,可能会由于乱序运行而导致其他问题。
  • 众所周知,集合视图难以提高性能,因为过去的一行单元格曾经在一次运行循环迭代中创建和配置。 在iOS 10中,此行为已更改为在多个运行循环迭代中扩展单元格创建。 有关优化集合视图代码以利用此功能的提示,请参阅此WWDC视频

如果您仍然遇到问题,请发布更多示例代码; 最重要的是, configureUI的内容。 谢谢!


Turned out I was focusing on the wrong side. My lack of experience with Realm made me feel that there must be something wrong I did with Realm. However, the true culprit was I forgot to define the path for shadow of my customed cell, which is really expensive to draw repeatedly. I did not find this until I used the time profile to check which methods are taking the most CPU, and I should have done it in the first place.

相关问答

更多

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。