1

I deployed one program onto several servers (suppose the server IPs and the ports providing the service are 192.168.1.101:10001, 192.168.1.102:10001, 192.168.1.103:10001, 192.168.1.104:10001). They are all listening requests using the Linux socket apis and can finish the task independently.

Now, I want to concurrently send data to all four servers, so that they can concurrently executing the tasks.

I am sending the data using one Windows 10 PC, using C++ Socket. The basic procedure of send_data is as follows:

void send_data(string& server_ip, string& server_port, vector<char>& buf) {
    struct addrinfo ...;           // set the server information
    SOCKET socket = socket(...);   // create the socket object
    connect(socket, ...);          // connect the server
    send(socket, buf, ...);        // send the buf data
}

This is OK when sending sequentially data into the four servers, e.g.,

vector<char> bufdata(...);
char* server_ips = {"192.168.1.101", "192.168.1.102", "192.168.1.103", "192.168.1.104"};
char* port = "10001";
for (int i = 0; i < 4; ++i) {
    send_data(server_ips[i], port, bufdata);
}

What I expect is the host client can concurrently send the data. I have tried the following method:

for (int i = 0; i < 4; ++i) {
    std::thread t(send_data, server_ips[i], port, bufdata); 
}

But the program will exit with no luck.

Could you please help give some advice? Thanks.

mining
  • 3,557
  • 5
  • 39
  • 66

2 Answers2

2

Not sure this is the only problem, but given what you shared, the main thread is not waiting for the worker threads to finish their tasks.

Per this answer: When the main thread exits, do other threads also exit?, the process will be terminated when the main thread returns from main().

Proposed fix:

int main() {
    // .. your logic here
    std::vector<std::thread> threads;
    for (int i = 0; i < 4; ++i) {
        std::thread t(send_data, server_ips[i], port, bufdata); 
        threads.push_back(std::move(t));
    }

    for (int i = 0; i < 4; ++i) {
        if (threads[i].joinable())
            threads[i].join(); // wait for threads[i] to finish
    }

    // .. clean up
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Mouze
  • 54
  • 5
  • 1
    `std::thread t(send_data, server_ips[i], port, bufdata); threads.push_back(std::move(t));` can be simplified to `threads.emplace_back(send_data, server_ips[i], port, bufdata);` Also, you don't need to check `joinable()` before calling `join()` in this use case – Remy Lebeau Oct 30 '21 at 23:02
1

You aren't joining or detaching the threads causing the program to exit with errors. Store the threads in an array so you can join them or call detach in your loop.

Zack R.
  • 27
  • 2