如何在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
的上半部分用-1
来evI->data.u64
setNew_Connection
通常接受像添加epoll等新套接字的东西
EPOLLET
。现在一切都运行得非常好,除非在以下情况下它失败,因为
events
只在epoll_wait
更新,所以连接闭包不会影响n
事件,直到返回到while(1)
循环的顶部。
epoll_wait
用在事件结构表中排队的3个事件epoll_wait
。- 第一个事件(n = 0)是在代码决定关闭连接(例如文件描述符8)之后的传入数据,因为它不再需要。
- 第二个事件(n = 1)是传入的新连接。
accept4
指定最近可用的fd:8。setNew_Connection
将其添加到epoll列表中。- 第三个事件是在步骤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 ofevI->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 theepoll_wait
so a connection closure does not affect then
events until after returning to the top of thewhile(1)
loop.
epoll_wait
unblocks with 3 events queued in the events struct table.- 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.
- 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.- 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 toepoll_wait
. How can I code around this problem?
原文:https://stackoverflow.com/questions/33382000
最满意答案
如果您在滚动时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.
相关问答
更多-
您可能还会遇到的两个原因 1.谷歌分析 如果设置为计算每个单元格视图。 它开始很快但随后变慢并且滞后,因为当您滚动太快时,谷歌分析会写入i / o(可能是一些缓存)。 2. DateTime解析 如果为每个单元格设置,则DateFormatter很难。 如果可能,请确保您有一个单身人士。 2 reasons that you might also encounter 1. Google analytics If you set up to count every cell view. It starts f ...
-
Android Realm性能(Android Realm Performance)[2023-08-23]
应该 public Observable- > getDatabaseChangeObserver(final String accountId) {
return RealmDatabaseProvider.getInstance(configuration,
realm -> realm
.where(InboxRealmEntity.class)
.contains ...
-
何时使用UICollectionView而不是UITableView?(When to use UICollectionView instead of UITableView?)[2024-02-03]
这取决于要求。 应用程序流程如何确定将哪种类型的UI集成到应用程序中。 人们主要使用UICollectionview来创建具有网格中显示的多个图像的UI类型。 这将使用UITableView具有复杂的逻辑,但是使用UICollectionview ,这将很容易。 当使用UICollectionview ,您不需要通过获取所选项目值来设置带有标签或其他内容的按钮。 你可以简单地获取-(void)collectionView:(UICollectionView *)collectionView didSelec ... -
这是我在我的测试项目中用来实现你想要的UICollectionViewDelegateFlowLayout 。 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { ...
-
使用一个collectionview IOS滚动多个UICollectionView(Scroll Multiple UICollectionView with one collectionview IOS)[2022-04-03]
好的我已经检查了我的代码,我的工作是:我在屏幕的左侧有一个tableView,其余的是UIScrollView,在其中我在顶部有一个宽度等于collectionView.contentSize的视图.width,并在该视图下方,collectionView,其高度等于屏幕高度,宽度等于其contentSize.width。 之后,ScrollView只能水平滚动,而collectionView只能垂直滚动,所以,当你水平滚动时,tableView会停留,标题视图和集合会水平滚动,如果你垂直滚动,标题视图会保 ... -
Realm / iOS:UICollectionView的凹凸不平的滚动性能(Realm/iOS: Bumpy scrolling performance for UICollectionView)[2022-08-29]
如果您在滚动时UI很崎岖,它只是意味着您在collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell执行的操作collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell太重了。 Realm ... -
let queue = dispatch_queue_create("loader", nil) dispatch_async(queue) { () -> Void in //download the image do stuff //like data = NSData(contentsOfURL: url) //move back in main thread dispatch_async(dispatch_get_main_queue(),{ //set the image. // ...
-
您可以为集合视图打开分页,它将具有该效果。 转到添加了集合的xib文件或故事板,并在其属性下启用分页。 You can turn paging on for the collection view and it will have that effect. Go to the xib file or storyboard that has the collection added and enable paging under its properties.
-
布局更改后,子视图似乎存在错误。 There appears to be a bug with subviews being kept around after layout changes.
-
首先,我想说,同时看到几个玩家在行动中有点疯狂:无论如何,这是一项繁重的渲染任务。 据我所知,简单地将视频缩放/重新构建为较小的尺寸并不会减少渲染的内容:如果要渲染100x100的图片并在10x10的帧中渲染它,它仍然会消耗相同的内容原始图片消耗的内存量; 视频也是如此。 因此,请尝试使您的视频资源具有与您呈现它们的帧相似的分辨率。 First I want to say it's a bit crazy to see several players in action at the same time: ...