为什么在发布模式下不访问for循环,但是在调试中它可以正常工作

时间:2019-04-15 12:26:23

标签: c++ sockets c++17

我的问题是我在Windows上编码了服务器/客户端应用程序。现在,在调试模式下,一切正常运行,并且应该正常运行,但是在发布模式下,服务器不接收或发送消息。

我认为是由于这个原因,导致无法访问无限for循环内的for循环。我也尝试了一段时间来实现此解决方案,但没有成功。我认为这可能是我在条件字段中调用函数的问题,因为当我将i与整数进行比较时,就可以访问它。同样有趣的是,当我在内部for循环之前执行std :: cout某些操作时,尽管我正在条件字段中调用该函数,也可以访问该循环。

#include <iostream>
#include <thread>
#include "server.cpp"

//gets defined in server.cpp
void server::acceptConn() {
    u_long mode =1;
    for(;;){
        int len = sizeof(incAddr[connectedSocks]);
        if((inc_sock[connectedSocks] = accept(serv,(struct sockaddr *)&incAddr[connectedSocks],&len))!= SOCKET_ERROR){
            std::cout<<"client connected : "<<inet_ntoa(incAddr[connectedSocks].sin_addr)<<std::endl;
            ioctlsocket(inc_sock[connectedSocks],FIONBIO,&mode);
            connectedSocks++;
        }
    }
}

int main() {
    server ser;
    ser.init_Server();
    std::thread t(&server::acceptConn,&ser);
    char buf[1024];
    for(;;){
        for(int i=0 ; ser.getCounter()>i;i++){
            if (recv(ser.getInc_Sock()[i], buf, sizeof(buf), 0) == SOCKET_ERROR) {

            } else{
                for (int x = 0; x < ser.getCounter(); x++) {
                    if(x==i){//just that the message doesnt get send back to the sender}
                    else{
                        if (send(ser.getInc_Sock()[x], buf, sizeof(buf), 0) == SOCKET_ERROR) {
                            std::cout<<"send failed : "<<WSAGetLastError()<<std::endl;
                        }
                    }
                }
            }
        }
    }
}

int getCounter(){return  connectedSocks;};//in server.h




结果应该是服务器具有已连接的袜子列表,并将消息分发给每个人。现在,当我在调试模式下运行它时,一切正常。可能是什么问题?

1 个答案:

答案 0 :(得分:1)

您的代码在两个线程之间缺少任何形式的同步。工作线程写入数据,而主线程读取数据。但是由于它们之间(mutex / atomics / etc)之间没有同步,因此从主线程的每次读取都是与工作线程的写入的数据竞争。

数据竞争是未定义的行为。因此,允许编译器编译主线程,就像没人写数据一样。

当将myParam放入循环中时,此操作有效,因为std::cout需要某种形式的同步,以防止多个线程同时写入标准输出。因此,您实际上是在搭载这种内部同步。但是您不应该依赖于此。您应该改用正确的同步原语。