Galarzaa90
Galarzaa90

Reputation: 180

Using threads on C++ on Raspbian, Can't compile

I'm trying to make a simple TCP server program for my Raspberry Pi 2. I already made the initial server code and it works, but then, I tried to implement a thread exclusively for the server and I haven't been able to compile since then.

#include <iostream>
#include <thread>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int serverTask(int port){
    int n;
    char buffer[256];
    /* Socket File Descriptors */
    int socketFd, socketFdNew;
    socklen_t clientLength;

    struct sockaddr_in serverAddress, clientAddress;

    /* TCP Socket */
    socketFd = socket(AF_INET, SOCK_STREAM, 0);
    if(socketFd < 0){
        error("ERROR opening socket\n");
    }

    /* Fills serverAddress with zeroes */
    bzero((char *) &serverAddress, sizeof(serverAddress));

    /* ServerAddress configuration */
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(port);

    /* Biding socket to server address */
    if(bind(socketFd, (struct sockaddr *) &serverAddress,sizeof(serverAddress)) < 0){
        error("ERROR on binding");
    }

    /* Listen for incoming connections, 5 is the number of queued devices */
    listen(socketFd,5);

    /* accept freezes the running thread until a client is found */
    clientLength = sizeof(clientAddress);
    socketFdNew = accept(socketFd, (struct sockaddr *) &clientAddress, &clientLength);
    if (socketFd < 0){
        error("ERROR on accept");
    }

    /* Fill buffer with zeroes */
    bzero(buffer,256);

    /* Reads up to 255 characters in the socket */
    n = read(socketFdNew, buffer, 255);
    if (n < 0){
        error("ERROR reading from socket");
    }

    printf("Received: %s\n",buffer);

    /* Responds with placeholder value */
    n = write(socketFdNew,"40.12\n",7);
    if (n < 0){
        error("ERROR writing to socket");
    }
    close(socketFdNew);
    close(socketFd);
    return 0;
}

int main()
{
    std::thread serverTask(7000);

    std::cout <<"Hello World!\n";

    serverTask.join();
    return 0;
}

My first attempt was simply building the code as any other code using g++ -Wall -o "main" "main.cpp"

Which got me the following error:

In file included from /usr/include/c++/4.6/thread:35:0, from main.cpp:2: /usr/include/c++/4.6/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options. main.cpp: In function 'int main()': main.cpp:79:2: error: 'thread' is not a member of 'std' main.cpp:79:14: error: expected ';' before 'serverTask' main.cpp:84:13: error: request for member 'join' in 'serverTask', which is of non-class type 'int(int)' Compilation failed.

So then I tried using C++11, so I recompiled with g++ -Wall -std=c++0x -pthread -o "main" "main.cpp" and I got the following:

In file included from /usr/include/c++/4.6/thread:39:0, from main.cpp:2: /usr/include/c++/4.6/functional: In member function 'void std::_Bind_result<_Result, _Functor(_Bound_args ...)>::__call(std::tuple<_Args ...>&&, std::_Index_tuple<_Indexes ...>, typename std::_Bind_result<_Result, _Functor(_Bound_args ...)>::__enable_if_void<_Res>::type) [with _Res = void, _Args = {}, int ..._Indexes = {}, _Result = void, _Functor = int, _Bound_args = {}, typename std::_Bind_result<_Result, _Functor(_Bound_args ...)>::__enable_if_void<_Res>::type = int]': /usr/include/c++/4.6/functional:1378:24: instantiated from 'std::_Bind_result<_Result, _Functor(_Bound_args ...)>::result_type std::_Bind_result<_Result, _Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {}, _Result = void, _Functor = int, _Bound_args = {}, std::_Bind_result<_Result, _Functor(_Bound_args ...)>::result_type = void]' /usr/include/c++/4.6/thread:117:13: instantiated from 'void std::thread::_Impl<_Callable>::_M_run() [with _Callable = std::_Bind_result]' main.cpp:86:1: instantiated from here /usr/include/c++/4.6/functional:1287:4: error: '((std::_Bind_result*)this)->std::_Bind_result::_M_f' cannot be used as a function Compilation failed.

My last resort was installing g++4.9. Once installed, I tried with g++-4.9 -Wall -std=gnu++0x -pthread -o "main" "main.cpp" and I got the following result:

In file included from /usr/include/c++/4.9/thread:39:0, from main.cpp:2: /usr/include/c++/4.9/functional: In instantiation of 'struct std::_Bind_simple': /usr/include/c++/4.9/thread:140:47: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = int; _Args = {}]' main.cpp:79:29: required from here /usr/include/c++/4.9/functional:1665:61: error: no type named 'type' in 'class std::result_of' typedef typename result_of<_Callable(_Args...)>::type result_type; ^ /usr/include/c++/4.9/functional:1695:9: error: no type named 'type' in 'class std::result_of' _M_invoke(_Index_tuple<_Indices...>) ^ Compilation failed.

Now I'm confused and I don't know what I'm doing wrong.

Update 1: Trying with a simpler code

#include <iostream>
#include <thread>
#include <stdio.h>


int serverTask(int port){
    return 0;
}

int main()
{
    std::thread serverTask(7000);


    std::cout <<"Hello World!\n";

    serverTask.join();
    return 0;
}

The results remained the same:

g++-4.9 -Wall -std=gnu++0x -pthread -o "test" "test.cpp" (in directory: /home/pi/TempServer) In file included from /usr/include/c++/4.9/thread:39:0, from test.cpp:2: /usr/include/c++/4.9/functional: In instantiation of 'struct std::_Bind_simple': /usr/include/c++/4.9/thread:140:47: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = int; _Args = {}]' test.cpp:12:29: required from here /usr/include/c++/4.9/functional:1665:61: error: no type named 'type' in 'class std::result_of' typedef typename result_of<_Callable(_Args...)>::type result_type; ^ /usr/include/c++/4.9/functional:1695:9: error: no type named 'type' in 'class std::result_of' _M_invoke(_Index_tuple<_Indices...>) ^ Compilation failed.

Upvotes: 1

Views: 4465

Answers (1)

M.M
M.M

Reputation: 141574

This line:

std::thread serverTask(7000);

declares a variable called serverTask and you try to pass 7000 as the name of the function to run in the thread. However 7000 is not a function. Unfortunately g++ gives very cryptic error messages here.

You probably meant:

std::thread foo(serverTask, 7000);

to start a thread with the function call serverTask(7000).

Upvotes: 4

Related Questions