在 Raspbian 上使用 C++ 上的线程,无法编译
Using threads on C++ on Raspbian, Can't compile
我正在尝试为我的 Raspberry Pi 2 制作一个简单的 TCP 服务器程序。我已经制作了初始服务器代码并且它可以工作,但是后来,我尝试专门为服务器实现一个线程并且从那以后我一直无法编译。
#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;
}
我的第一次尝试只是像使用任何其他代码一样使用 g++ -Wall -o "main" "main.cpp"
构建代码
这让我出现了以下错误:
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.
然后我尝试使用 C++11
,所以我用 g++ -Wall -std=c++0x -pthread -o "main" "main.cpp"
重新编译并得到以下内容:
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.
我最后的选择是安装 g++4.9。安装后,我尝试使用 g++-4.9 -Wall -std=gnu++0x -pthread -o "main" "main.cpp"
并得到以下结果:
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.
现在我很困惑,我不知道自己做错了什么。
更新 1:尝试使用更简单的代码
#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;
}
结果保持不变:
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.
这一行:
std::thread serverTask(7000);
声明了一个名为 serverTask
的变量,您尝试将 7000
作为函数名称传递给线程中的 运行。但是 7000
不是函数。不幸的是,g++ 在这里给出了非常神秘的错误消息。
你的意思可能是:
std::thread foo(serverTask, 7000);
使用函数调用启动线程 serverTask(7000)
。
我正在尝试为我的 Raspberry Pi 2 制作一个简单的 TCP 服务器程序。我已经制作了初始服务器代码并且它可以工作,但是后来,我尝试专门为服务器实现一个线程并且从那以后我一直无法编译。
#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;
}
我的第一次尝试只是像使用任何其他代码一样使用 g++ -Wall -o "main" "main.cpp"
这让我出现了以下错误:
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.
然后我尝试使用 C++11
,所以我用 g++ -Wall -std=c++0x -pthread -o "main" "main.cpp"
重新编译并得到以下内容:
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.
我最后的选择是安装 g++4.9。安装后,我尝试使用 g++-4.9 -Wall -std=gnu++0x -pthread -o "main" "main.cpp"
并得到以下结果:
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.
现在我很困惑,我不知道自己做错了什么。
更新 1:尝试使用更简单的代码
#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;
}
结果保持不变:
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.
这一行:
std::thread serverTask(7000);
声明了一个名为 serverTask
的变量,您尝试将 7000
作为函数名称传递给线程中的 运行。但是 7000
不是函数。不幸的是,g++ 在这里给出了非常神秘的错误消息。
你的意思可能是:
std::thread foo(serverTask, 7000);
使用函数调用启动线程 serverTask(7000)
。