0

I am new in the c++ programming and I have a question about threading. I have experienced in c# and java that; When you start a threading, it works independently and separates itself from the main thread. In other words child thread not blocks the main one.

However In c++ It seems that, it is not working in that way. When I use the join it blocks the code, when I use the detach it kills the thread.

I am using threading code sample for socket server thread, detach is killing the socket listening.

My aim, is to run the while looped listening socket independently and continuously run on the background. It shouldn't block the main thread flow.

How can be done? Is there a brief code sample for it.

I would be vey happy, if you help about this.

Here is my code below, I don't know what is wrong with it. I have to make: Thread has to run forever, It has to listen and answer.

#ifndef UNICODE
#define UNICODE 1
#endif

#pragma comment(lib, "Ws2_32.lib")
#include "soketSample.h"
    
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <ws2tcpip.h>
#include <winsock2.h>
//#include <MSWSock.h>
#include <share.h>
#include <atltypes.h>
#include <thread>





using namespace std;



string convertToString(char* a, int size)
{
    int i;
    string s = "";
    for (i = 0; i < size; i++) {
        s = s + a[i];
    }
    return s;
}



int socketSample() 
{
    WSADATA wsa;
    SOCKET s, new_socket;
    struct sockaddr_in server, client;
    int c;
    char *message, server_reply[2000];
    int recv_size;

    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
        printf("Failed. Error Code : %d", WSAGetLastError());
        return 1;
    }

    printf("Initialised.\n");

    //Create a socket
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d", WSAGetLastError());
    }


    printf("Socket created.\n");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(30035);

    //Bind
    if (::bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d", WSAGetLastError());
    }

    puts("Bind done");

    

    //Listen to incoming connections
    listen(s, 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");

    
    c = sizeof(struct sockaddr_in);
    new_socket = accept(s, (struct sockaddr*)&client, &c);
    if (new_socket == INVALID_SOCKET)
    {
        printf("accept failed with error code : %d", WSAGetLastError());
    }

    puts("Connection accepted");


    //Reply to client
    message = "Hello Client , Hello I will receive the connections from now on \n";
    send(new_socket, message, strlen(message), 0);


    //Declare and initialize variables.
    recv_size = 5;


    while (recv_size > 0)
    {
        recv_size = recv(new_socket, server_reply, 2000, 0);

        if (recv_size == 0 || recv_size == WSAECONNRESET)
        {
            printf("Client: Connection Closed.\n");
            break;
        }
        else
        {
            printf("Client: recv() is OK.\n");
            int server_reply_size = sizeof(server_reply);
            string result = convertToString(server_reply, server_reply_size);
            const char * k = result.c_str();
            //result = marshal_as<string>
            puts(k);
        }
        
                
    }


    puts("Data Send\n");
    getchar();

    closesocket(s);
    WSACleanup();

    return 0;
    
}

int main()
{
    std::thread thread_obj(socketSample);
    thread_obj.join();//if a I put join it blocks it.
    thread_obj.detach(); //in here detach kills my socket listen thread.
    puts("Thread is perfectly active..............");
    return 0;
}
  • You just store the `std::thread` object somewhere until you don't need the thread anymore (like, when the application is closed) and call `join` then. – John Cvelth Jan 22 '21 at 09:16
  • Can you provide a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example)? – Jose Jan 22 '21 at 09:20
  • "It seems that"... No, show the code that makes you think that. – manuell Jan 22 '21 at 09:23
  • detaching a thread does not kill it. If you have problems with some code please include a [mcve] – 463035818_is_not_an_ai Jan 22 '21 at 09:24
  • `detach` does not kill your thread, it is the `main` function exiting that terminates your process and all your threads. You should really do a `join` in this case. – Nicolas Dusart Jan 22 '21 at 10:26
  • I have edited my question, to show what am I doing wrong ? –  Jan 22 '21 at 10:36
  • you should look how to write a daemon instead: https://stackoverflow.com/questions/17954432/creating-a-daemon-in-linux – Nicolas Dusart Jan 22 '21 at 10:38
  • Sorry I have to write it in 64bit windows , Is daemon available in that platform? –  Jan 22 '21 at 10:41
  • what I do for emulating a fork in WIndows is check for an argument in `argv` telling that I'm running as a detached process. If argument is missing, I restart the process with the argument using `CreateProcessA` and `DETACHED_PROCESS | CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP` flags. There are better ways to do it though, but this is easy to implement. – Nicolas Dusart Jan 22 '21 at 10:46
  • Sorry Could you be more clear, I have not much experience in c++. Do you mean that, this can be done with different coding rather than threading . –  Jan 22 '21 at 10:59
  • I got it . int main() finishes, main thread ends , so the child thread terminates at the end. :) –  Jan 22 '21 at 12:14

0 Answers0