相关疑难解决方法(0)

如何将TCP套接字更改为非阻塞?

你如何使套接字无阻塞?

我知道这个fcntl()功能,但我听说它并不总是可靠的.

c sockets

34
推荐指数
7
解决办法
13万
查看次数

如何避免使用`asio :: ip :: tcp :: iostream`进行数据竞争?

我的问题

当使用两个线程发送和接收时,如何避免数据竞争asio::ip::tcp::iostream

设计

我正在编写一个使用asio::ip::tcp::iostream输入和输出的程序.程序通过端口5555接受来自(远程)用户的命令,并通过相同的TCP连接将消息发送给用户.因为这些事件(从用户接收的命令或发送给用户的消息)是异步发生的,所以我有单独的发送和接收线程.

在这个玩具版本中,命令是"一个","两个"和"退出".当然"退出"退出该计划.其他命令不执行任何操作,任何无法识别的命令都会导致服务器关闭TCP连接.

传输的消息是简单的序列编号消息,每秒发送一次.

在这个玩具版本和我正在尝试编写的实际代码中,发送和接收进程都使用阻塞IO,因此似乎没有一种使用std::mutex其他同步机制的好方法.(在我的尝试中,一个进程会获取互斥锁然后阻塞,这对此无效.)

构建和测试

为了构建和测试它,我在64位Linux机器上使用gcc版本7.2.1和valgrind 3.13.建立:

g++ -DASIO_STANDALONE -Wall -Wextra -pedantic -std=c++14 concurrent.cpp -o concurrent -lpthread
Run Code Online (Sandbox Code Playgroud)

要测试,我使用以下命令运行服务器:

valgrind --tool=helgrind --log-file=helgrind.txt ./concurrent 
Run Code Online (Sandbox Code Playgroud)

然后我telnet 127.0.0.1 5555在另一个窗口中使用来创建与服务器的连接.什么helgrind正确地指出的是,有一个数据竞争,因为两者runTxrunRx试图以异步方式访问相同的数据流:

== 16188 ==线程#1在0x1FFEFFF1CC读取大小1期间可能发生数据竞争

== 16188 ==持有的锁:无

...更多的线路被省略了

concurrent.cpp

#include <asio.hpp>
#include <iostream>
#include <fstream>
#include <thread>
#include <array>
#include <chrono>

class Console {
public:
    Console() :
        want_quit{false},
        want_reset{false}
    {}
    bool getQuitValue() const { return want_quit; }
    int run(std::istream …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading tcp boost-asio c++14

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

标签 统计

boost-asio ×1

c ×1

c++ ×1

c++14 ×1

multithreading ×1

sockets ×1

tcp ×1