小编hae*_*lix的帖子

TCP:何时生成EPOLLHUP?

另请参阅此问题,到目前为止尚未回答。

EPOLLHUP即使在man和内核文档中也有很多关于的困惑。人们似乎相信,当一个描述符轮询它返回本地关闭书写,即shutdown(SHUT_WR),即导致相同的呼叫EPOLLRDHUP 在对等。但这是不正确的,在我的实验中,我得到了EPOLLOUTEPOLLHUP之后没有得到shutdown(SHUT_WR)(是的,变得可写是违反直觉的,因为写作的一半是封闭的,但这不是问题的重点)。

这个很穷,因为它EPOLLHUP说到挂起发生在关联的文件描述符上时,而没有说“挂断”是什么意思-对方做了什么?发送了什么数据包?另一篇文章只是使事情更加混乱,对我来说似乎是完全错误的。

我的实验表明,EPOLLHUP一旦双向交换EOF(FIN数据包),即双方都发出,就到达了shutdown(SHUT_WR)。它与无关SHUT_RD,我从不称呼它。也与无关close。在数据包方面,我怀疑EPOLLHUP主机发送的FIN会引起确认,即终止发起方在4向关机握手的第3步中引发此事件,而对等方在第4步中引发(请参见此处))。如果得到确认,那就太好了,因为它填补了我一直在寻找的空白,即如何在不使用LINGER的情况下轮询非阻塞套接字以获得最终的确认。它是否正确?

(注意:我正在使用ET,但我认为与此无关)

示例代码和输出。

该代码在一个框架之中,我提取它的肉,用之外TcpSocket::createListenerTcpSocket::connectTcpSocket::accept,它做你所期望(这里没有显示)。

void registerFd(int pollFd, int fd, const char* description)
{
    epoll_event ev = {
        EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET,
        const_cast<char*>(description) // union aggregate initialisation, initialises …
Run Code Online (Sandbox Code Playgroud)

linux epoll tcp linux-kernel epollet

6
推荐指数
1
解决办法
1143
查看次数

JNI - 有没有办法让 JVM 调用 JNI_OnUnload ?

关于这方面的信息很少,例如2006 年的这个人们放弃了优雅地释放 JNI 资源。

JNI_OnUnload( Oracle 文档) 旨在当 JVM 中不再需要您的本机功能时释放资源(特别是“全局引用”)。本机库将像这样加载

static {
    System.loadLibrary("mylibjni"); // on Linux this translates to "libmylibjni.so"
}
Run Code Online (Sandbox Code Playgroud)

...但是 Java 没有提供明确的卸载方法。

发生了什么:在我的 lib 中,由于没有机会进行清理,lib 最终确实卸载了(我不明白什么时候,请参阅下面的调用堆栈),但是为时已晚,这会触发一些拥有 JNI 全局引用的全局变量调用DeleteGlobalRef失败:

# JRE version: OpenJDK Runtime Environment (10.0.2+13) (build 10.0.2+13)
# Java VM: OpenJDK 64-Bit Server VM (10.0.2+13, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# C  [libblahjni.so+0x9a7e6]  JNIEnv_::DeleteGlobalRef(_jobject*)+0x14
Run Code Online (Sandbox Code Playgroud)

深入研究一下,这是因为线程上没有JNIEnv执行卸载(我正在缓存环境thread_local)。当时尝试检索 Env 没有成功 …

c++ java java-native-interface shared-libraries jnienv

6
推荐指数
0
解决办法
1150
查看次数

如何在C ++程序的stacktrace中查看有用的信息(文件名,行号)

这是一个复杂的过程,因为它也取决于Boost版本和平台。

我正在使用boost stacktrace在某些断言失败的地方打印backtrace。有一些外部编译时和运行时dep,具体取决于您使用的是哪种模式(链接介绍了〜5个模式)。我更喜欢基于调试信息和导出信息的东西(我认为后者也可以在生产版本中使用)。但是,我可以得到既不默认模式或工作BOOST_STACKTRACE_USE_ADDR2LINEBOOST_STACKTRACE_USE_BACKTRACE-所有3只显示在我的实际的程序代码的调用堆栈地址-看到一个谷歌测试测试堆栈跟踪如下:

 0# 0x000055E47D43BDC2 in Debug/myprog
 1# 0x000055E47D489055 in Debug/myprog
 2# 0x000055E47D567FDF in Debug/myprog
 3# 0x000055E47D560CDE in Debug/myprog
 4# void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) in /usr/lib/libgtest.so.1.8.1
 5# testing::Test::Run() in /usr/lib/libgtest.so.1.8.1
 6# testing::TestInfo::Run() in /usr/lib/libgtest.so.1.8.1
 7# testing::TestCase::Run() in /usr/lib/libgtest.so.1.8.1
 8# testing::internal::UnitTestImpl::RunAllTests() in /usr/lib/libgtest.so.1.8.1
Run Code Online (Sandbox Code Playgroud)

我尝试了什么:-rdynamic,-fno-pie和-fPIC,(我已经在-O0上),-ggdb3而不是默认的-g3,没有任何函数名称显示出来。

相关:这个这个

我正在使用:gcc 8.2,boost 1.69(stracktrace库的仅标头模式),Arch Linux(在该系统上,我必须手动安装未打包的libbacktrace,所以我更喜欢使用ADDR2LINE方法)


编辑:更新到最新的boost.stacktrace的链接。


Edit2:我注意到boost.stacktrace文档包含此提示

由于地址空间布局随机化,共享库中的函数名称可能无法解码。总比没有好。

...听起来很有帮助,但对我来说却是另一回事,我没有在自己的可执行文件中获取符号,但是libgtest.so例如。因此,好像调试信息设置有问题。任何想法表示赞赏。

c++ boost stack-trace debug-symbols

5
推荐指数
1
解决办法
362
查看次数

如何使用libreoffice WEBSERVICE calc功能?

这曾经在 libreoffice calc 中工作,但现在无法再工作了。

我在单元格中输入:(我的个人密钥已更改)

=WEBSERVICE("http://api.currencylayer.com/historical? access_key=123456&date=2021-03-08")

我应该返回一个 JSON(在浏览器中有效),但在 Calc 中我收到错误#VALUE!

我保存文档并重新加载它,出现一个横幅,上面写着“外部链接的自动更新已被禁用”。我单击“允许更新”,单元格更改为“Err:540”,它代表“外部内容已禁用”。

我尝试更改安全设置Tool > Options > LibreOffice > Security > Macro Security > changed from "High" (the default) to "Medium" (confirmation required before executing macros from untrusted sources"

..但没有成功。

我在 ArchLinux 上,尝试使用 libreoffice-still (7.0.4-2)、libreoffice-still (7.0.5-2) 和 libreoffice-fresh (7.1.2-2)。

我发现的解决方法是安装一个提供 GET 函数的插件,如此处所述但我非常希望使用内置方法来工作。这是一个错误吗?

web-services get libreoffice-calc

5
推荐指数
1
解决办法
3161
查看次数

转义用于sed替换的文件名

我怎样才能解决这个问题:

abc="a/b/c"; echo porc | sed -r "s/^/$abc/"
sed: -e expression #1, char 7: unknown option to `s'
Run Code Online (Sandbox Code Playgroud)

变量的替换$abc正确完成,但问题是$abc包含斜杠,这会混淆sed.我可以以某种方式逃脱这些斜线吗?

linux variables bash escaping sed

4
推荐指数
2
解决办法
2034
查看次数

谷歌模拟:为什么部分订购的期望难以满足总订购?

我主要使用GoogleMock的有序期望,因此所有内容EXPECT_CALL都写在testing::InSequence对象的范围内.

现在我想放松排序,所以我将期望分成2个序列.你会说测试应该通过,但是没有 - 它失败了,抱怨未满足的前提条件.我该如何解释这个?

编辑:我的代码的缩减版本:

//InSequence s;                                     // uncomment this and it works
for (int i = 1; i <= 2; ++i)
{
    {
        //InSequence s;                             // uncomment this and it doesn't work

        EXPECT_CALL(mock1, produceMessage(_))
            .WillOnce(DoAll(SetArgReferee<0>(val1), Return(false)))
            .WillOnce(DoAll(SetArgReferee<0>(val2), Return(false)))
            .WillOnce(DoAll(SetArgReferee<0>(val2), Return(false)));

        EXPECT_CALL(mock2, handleEvent(A<MyType>()));
        EXPECT_CALL(mock2, handleMessage(NotNull()));
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果InSequence嵌套在for循环中,我应该有一个部分顺序,这是一个宽松的要求,与InSequence在外面的情况相比.

我得到的错误:

Mock function called more times than expected - returning default value.
    Function call: handleMessage(0xd7e708)
          Returns: false
         Expected: to be called once
           Actual: called twice - …
Run Code Online (Sandbox Code Playgroud)

c++ expectations googlemock

4
推荐指数
1
解决办法
3040
查看次数

EPOLLRDHUP不可靠

我在客户端 - 服务器TCP连接上使用非阻塞读/写epoll_wait.

问题是,我无法使用EPOLLRDHUP标志可靠地检测到"对等关闭连接"事件.经常发生的是没有设置标志.客户端使用close()和服务器,大部分时间,接收从epoll_wait,一个EPOLLIN | EPOLLRDHUP事件.正如预期的那样,读取产生零字节.但有时只会EPOLLIN产生零字节.

使用调查tcpdump显示,据我所知,正常关机发生.我看到Flags [F.], Flags [F.], Flags [.]一系列事件,应该对应于FIN,FIN和ACK.SO_LINGER无处可去.

我考虑在零字节读取时处理"对等关闭",但是,EPOLLIN | EPOLLRDHUP当对等体发送并立即关闭连接时,有可能得到一个非零字节可用的事件 - 我需要以自己为基础的情况这个EPOLLRDHUP.建议?

epoll tcp

4
推荐指数
1
解决办法
2889
查看次数

结束(过去的)迭代器的STL迭代器重新验证?

查看关于过去的迭代器失效的相关问题: 这个,这个.

这更像是一个设计问题,即(在STL或其他地方)是否有像过去的迭代器"重新验证"这样的概念?

我的意思和用例:假设一个算法需要"尾随"一个容器(如队列).它遍历容器直到end()到达,然后暂停; 独立于此,程序的另一部分将队列中的更多项目排入队列.算法(EDIT)如何有效地告诉"有更多的项目已经入队",同时保持以前的过去的迭代器(称之为tailIt)?(这意味着它能够检查是否tailIt == container.end() 仍然,如果这是假的,则conclude tailIt现在有效并指向插入的第一个元素).

请不要将这个问题视为"不,没有" - 我正在寻求围绕如何以惯用的方式设计一些逻辑的判断,并且有很多选择(事实上,所讨论的迭代器是一只手- 我可以提供此属性的构建数据结构- 结束()重新验证 - 但我想判断它是否是一个好主意).


编辑:明确我们有迭代器tailIt 引用container.我正在尝试做的一个简单的解决方法是,还要记住count:=您处理了多少项,然后检查container.size() == count仍然是,如果没有,请container[count]从那里寻求并继续处理.这带来了许多缺点(额外状态,假设容器不从前面弹出(!),随机访问以进行有效搜索).

c++ algorithm iterator stl invalidation

4
推荐指数
2
解决办法
116
查看次数

std :: cin真的很慢

所以我试图给自己写一个linux管道的命令.可以把它想象成gnu'cat'或'sed'的复制品,它从stdin获取输入,做一些处理并写入stdout.

我最初写了一个AWK脚本,但想要更多性能,所以我使用了以下c ++代码:

std::string crtLine;
crtLine.reserve(1000);
while (true)
{
    std::getline(std::cin, crtLine);
    if (!std::cin) // failbit (EOF immediately found) or badbit (I/O error)
        break;

    std::cout << crtLine << "\n";
}
Run Code Online (Sandbox Code Playgroud)

这正是cat(没有任何参数).事实证明,这个程序和它的awk一样慢,并且远不及cat那么快.

在1GB文件上测试:

$time cat 'file' | cat | wc -l
real    0m0.771s

$time cat 'file' | filter-range.sh | wc -l
real    0m44.267s
Run Code Online (Sandbox Code Playgroud)

我没有使用getline(istream,string)来尝试cin.getline(缓冲区,大小),但没有改进.这很令人尴尬,这是一个缓冲问题吗?我也试过一次取100KB而不是一行,没有帮助!有任何想法吗?

编辑:你们所说的有道理,但罪魁祸首不是字符串构建/复制,也不是扫描换行符.(也不是缓冲区的大小).看看这两个程序:

char buf[200];
while (fgets(buf, 200, stdin))
    std::cout << buf;

$time cat 'file' | ./FilterRange > /dev/null
real    0m3.276s




char buf[200];
while (std::cin.getline(buf, 200))
    std::cout << buf << …
Run Code Online (Sandbox Code Playgroud)

c++ pipeline cout cin

3
推荐指数
1
解决办法
3232
查看次数

std::byte 指针应该用于指针运算吗?

它似乎std::byte已经成为(在 C++17 中)处理保存对象表示的缓冲区的方式,但目前尚不清楚这种意图是否仍然允许执行指针算术。

标题中的问题是故意措辞应该的,因为我正在寻找推荐。例如,void*可以作为 gcc 扩展用于指针算术,但不是标准的(至少对于 C这样),因此可能但不是推荐

我知道的动机std::byte是将字符和数字方面与byte的概念分开。但与此同时,指针算法是否会留下来?

编辑:调整以澄清我希望使用std::byte*不使用std::bytes 中的指针存储的数值进行“指针算术”

c++ memory byte void pointer-arithmetic

0
推荐指数
1
解决办法
415
查看次数