Нужно ли блокировать функции-члены класса, если его объекты выполняются в нескольких потоках?

Я работаю с сетевым проектом на основе C++, используя библиотеку winsock. Код является:

class NetworkCom
{
private:
    SOCKADDR_IN ClientAddress;
    int ClientAddressSize;
    SOCKET SenderSocket;
public:
    NetworkCom(SOCKET& sock)
    {
        ClientAddressSize = sizeof(ClientAddress);
        getpeername(sock,(SOCKADDR*)&ClientAddress,&ClientAddressSize);

        sock = socket(AF_INET,SOCK_STREAM,0);
        SenderSocket = socket(AF_INET,SOCK_STREAM,0);
    }

    int SendData(char message[])
    {
        int val;
        val = send(sock,message,sizeof(message),0); // if val <= 0 then error
        return val;     
    }   

    string RecieveData()
    {
        string message;
        char msg[100];

        connect(SenderSocket,(SOCKADDR*)&ClientAddress,&ClientAddressSize);
        recv(SenderSocket,msg,100,0);
        message = msg;

        return message;
    }

    ~NetworkCom()
    {
        cout<<"Closing Connection..";
        closesocket(SenderSocket);
        closesocket(sock);
    }
  };

Я собираюсь создать новый объект NetworkCom для каждого нового клиента в новом потоке. Поэтому, когда я делаю это, мне нужно использовать mutex для блокировки функции-члена класса всегда, когда объект в потоке использует функции-члены SendData и RecieveData.

Если мне нужно использовать мьютекс.... Есть ли способ сделать это без мьютекса?

1 ответ

Как и большинство API сокетов, Winsock не любит параллельный доступ к одному и тому же сокету:

send Не следует вызывать один и тот же поток-ориентированный сокет одновременно из разных потоков, поскольку некоторые провайдеры Winsock могут разбивать большой запрос на отправку на несколько передач, и это может привести к непреднамеренному чередованию данных из нескольких одновременных запросов на отправку в одном потоковом сокете,

Из MSDN, recv имеет аналогичные ограничения.

Поэтому, если вы совместно используете один и тот же сокет между несколькими потоками, весь доступ к этому сокету должен быть синхронизирован. Мьютекс является одним из способов достижения этой синхронизации. Если вы используете разные сокеты для разных потоков, вам не нужно синхронизировать, если вы не делитесь никакими другими (изменяемыми) данными между потоками.

Другие вопросы по тегам