cpp-ipc icon indicating copy to clipboard operation
cpp-ipc copied to clipboard

send函数无接收端也直接成功

Open huanglin2 opened this issue 1 year ago • 4 comments

环境:win10 vs2017 demo channel测试,无接收端的情况下(后启动) while (!cc.send(datas[i])) { // waiting for connection cc.wait_for_recv(2); // 这里等待2个连接的原因是,thread producer的cc自身也是一个连接(ipc::receiver) } send依旧会成功,导致发送端和接收端都处于recv死等待

huanglin2 avatar Feb 18 '24 07:02 huanglin2

ipc::channel mode is ipc::sender | ipc::receiver , 应该把当前channel也作为接收者了,所以貌似send一定成功?

huanglin2 avatar Feb 18 '24 07:02 huanglin2

额,你用的是哪个demo?确实如你所说,channel是一个全局的通道,进程可以接收到自己发出去的消息,但我在recv里把自己的消息丢弃了。虽然如此,双向通信还是建议用两个channel,性能会好很多。

你这个现象不确定是不是bug,完整测试用的是这段代码么?

while (!cc.send(datas[i])) {
// waiting for connection
cc.wait_for_recv(2); // 这里等待2个连接的原因是,thread producer的cc自身也是一个连接(ipc::receiver)
}

另外在问题出现之前是否有意外退出的行为?

mutouyun avatar Feb 20 '24 03:02 mutouyun

列子是这个,这个库对意外退出以后会有一些不确定行为吗?

using namespace std::literals;

std::vector<char const*> const datas = {
    "hello!",
    "foo",
    "bar",
    "ISO/IEC",
    "14882:2011",
    "ISO/IEC 14882:2017 Information technology - Programming languages - C++",
    "ISO/IEC 14882:2020",
    "Modern C++ Design: Generic Programming and Design Patterns Applied"
};

// thread producer
std::thread t1{ [&] {
    ipc::channel cc { "my-ipc-channel", ipc::sender | ipc::receiver };
    for (std::size_t i = 0; i < datas.size(); ++i) {
        // try sending data  先启动producter这里一定会成功
        while (!cc.send(datas[i])) {
            // waiting for connection
            cc.wait_for_recv(2); // 这里等待2个连接的原因是,thread producer的cc自身也是一个连接(ipc::receiver)
        }
        std::this_thread::sleep_for(1s);
        // recv ack
        std::printf("1 recving\n");
        auto dd = cc.recv();
        auto str = static_cast<char*>(dd.data());
        if (str == nullptr) {
            std::printf("ack: error!\n");
        }
        else {
            std::printf("ack: %c\n", str[0]);
        }
    }
    // quit
    cc.send(ipc::buff_t('\0'));
} };

// thread consumer
std::thread t2{ [&] {
    ipc::channel cc { "my-ipc-channel", ipc::sender | ipc::receiver };
    while (1) {
        std::printf("2 recving\n");
        auto dd = cc.recv();
        auto str = static_cast<char*>(dd.data());
        if (str == nullptr || str[0] == '\0') return;
        std::printf("2 recv: %s\n", str);
        // try sending ack
        while (!cc.send(ipc::buff_t('a'))) {
            // waiting for connection
            cc.wait_for_recv(2);
        }
    }
} };

t1.join();
t2.join();

huanglin2 avatar Feb 23 '24 07:02 huanglin2

对的,需要捕获signal,手动disconnect一下。主要是因为linux的共享内存文件是一直存在的,这会导致各种奇怪的问题。

mutouyun avatar Feb 25 '24 04:02 mutouyun