解决linux底下cmake编译使用C++ 11标准库自带的thread报错问题

2023-05-16

本人在编写linux底下socket编程测试服务端时候,发现使用std::thread函数时候,cmake编译通过,make编译失败 ,CMakeLists.txt如下:

cmake_minimum_required(VERSION 3.10)
project(Server)


set(SERVER_INC ./include)
message(STATUS,"SERVER_INC is ${SERVER_INC}")
include_directories(${SERVER_INC})
file(GLOB H_FILE ${SERVER_INC}/*.h)
message(STATUS,"H_FILE is ${H_FILE}")
set(SOURCE 
                main.cpp
                Server.cpp
                ${H_FILE})
message(STATUS,"SOURCE is ${SOURCE}")
add_executable(${PROJECT_NAME} ${SOURCE})  

Server.cpp如下

Server::Server(/* args */)
{
     Server::m_last_closed=-1;
     Server::m_isonline=false;
     
}

Server::~Server()
{
    for(int i=0;i<newSocket.size();i++)
    {
        detach(i);
    }
    closed();
}
void  Server::AcceptTask(descript_socket argv)
{
    try
    {
        /* code */

        int n=-2;
        struct descript_socket desc = (struct descript_socket) argv;
        
        std::  cerr << "服务端open client[ id:"<< desc.id <<" ip:"<< desc.ip <<" socket:"<< desc.socketfd<<" send:"<< desc.enable_message_runtime <<" ]" << std::endl;
        while(1)
        {
            n = recv(desc.socketfd, msg, MAXPACKETSIZE, 0);
            if(n != -1) 
            {
                if(n==0)
                {
                    Server::m_isonline=true;
                    
                    std::cerr << "服务端close client[ id:"<< desc.id <<" ip:"<< desc.ip <<" socket:"<< desc.socketfd<<" ]" << std::endl;
                    Server::m_last_closed = desc.id;
                    close(desc.socketfd);

                    int id = desc.id;
                    auto new_end = std::remove_if(newSocket.begin(), newSocket.end(),
                                                        [id](descript_socket device)
                                                            { return device.id == id; });
                    newSocket.erase(new_end, newSocket.end());

                    if(m_clientNum>0) 
                    {
                        m_clientNum--;
                    }
                    break;
                }
                msg[n]=0;
                desc.message = std::string(msg);
                std::lock_guard<std::mutex> guard(m_mutex);
                Message.emplace_back( desc );
            }
            usleep(600);
        }
     
        std::cerr << "exit thread: " << std::this_thread::get_id() << std::endl;
       

        

    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
       
    }
    
   
}

bool Server::SetUp(std::string ip,int port,int protocolType)
{
    try
    {
        
            /* code */
            //1.创建一个socket
        int m_sockfd=socket(AF_INET,(IPPROTO_TCP == protocolType)? SOCK_STREAM : SOCK_DGRAM,protocolType);

        if(m_sockfd<0)
        {
            std::cerr<<"服务端socket create fail"<<std::endl;
            return false;
        }
        else
        {
            std::cerr<<"服务端socket创建"<<std::endl;
        }
        //2.准备通讯地址(必须是服务器的)的IP
        memset(&m_serverAddress,0,sizeof(m_serverAddress));
        m_serverAddress.sin_family = AF_INET;
        m_serverAddress.sin_port = htons(port);//将一个无符号短整型的主机数值转换为网络字节顺序,即大尾顺序(big-endian)
        m_serverAddress.sin_addr.s_addr = inet_addr(ip.c_str());//net_addr方法可以转化字符串,主要用来将一个十进制的数转化为二进制的数,用途多于ipv4的IP转化。
        //3.bind()绑定
        //参数一:0的返回值(socket_fd)
        //参数二:(struct sockaddr*)&addr 前面结构体,即地址
        //参数三: addr结构体的长度
        int bind_fd=bind(m_sockfd,(struct sockaddr*)&m_serverAddress,sizeof(m_serverAddress));
        if(bind_fd<0)
        {
            std::cerr<<"服务端bind绑定失败"<<std::endl;
            return false;
        }
        else
        {
            
            std::cerr<<"服务端bind绑定成功"<<std::endl;
        }
        
        //4.监听客户端listen()函数
    //参数二:进程上限,一般小于30
        int listen_fd=listen(m_sockfd,30);
        if(listen_fd<0)
        {
            std::cerr<<"服务端listen error"<<std::endl;
            return false;
        }
        m_isonline=true;
        m_clientNum=0;
        return true;
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
        return false;
    }
    
   
}

bool Server::Accepted()
{
    try
    {
        //5.等待客户端的连接accept(),返回用于交互的socket描述符
        /* code */
        memset(&m_clientAddress,0,sizeof(m_clientAddress));
        socklen_t clientAddressLength=sizeof(m_clientAddress);
        descript_socket des_socket;
        des_socket.socketfd=accept(m_sockfd,(struct sockaddr*)&m_clientAddress,&clientAddressLength);
        des_socket.id=m_clientNum;
        des_socket.ip=inet_ntoa(m_clientAddress.sin_addr);
        newSocket.emplace_back(des_socket);
        std::cerr << "服务端accept client[ id:" << newSocket[m_clientNum].id<< 
                        " ip:" << newSocket[m_clientNum].ip << 
                    " handle:" << newSocket[m_clientNum].socketfd << " ]" << std::endl;
        if(newSocket[m_clientNum].socketfd<0)
        {
            std::cerr<<"服务端newSocket"<<"clientNum="<<m_clientNum<<"accept失败"<<std::endl;
        }
         std::thread t(&Server::AcceptTask,this,newSocket[m_clientNum]);
      
       
        
        m_isonline=true;
        m_clientNum++;
        return true;

    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
        return false;
    }
    
    
}
std::vector<descript_socket> Server::getMessage()
{  
 
        /* code */
          std::lock_guard<std::mutex> guard(m_mutex);
            return Message; 

    


}
bool Server::Send(std::string msg,int id)
{
    try
    {
        /* code */
         int Sendfd=send(newSocket[id].socketfd,msg.c_str(),sizeof(msg),0);
            if(Sendfd<0)
            {
                std::cerr<<"服务端Sendfd<0,send失败"<<std::endl;
                return false;
            }
            return true;
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
        return false;
    }
    
  
}
std::string Server::get_ip_addr(int id)
{
	return newSocket[id].ip;
}

bool Server::is_online() 
{
	return m_isonline;
}

void Server::detach(int id)
{
	close(newSocket[id].socketfd);
	newSocket[id].ip = "";
	newSocket[id].id = -1;
	newSocket[id].message = "";
} 

void Server::closed() 
{
   close(m_sockfd);
}
int Server::get_last_closed_sockets()
{
	return Server::m_last_closed;
}
void Server::clean(int id)
{
	
	memset(msg, 0, MAXPACKETSIZE);
}

运行cmake .

lx@lx-virtual-machine:~/my-codes/C++/Others/Socket/Server$ cmake .
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
STATUS,"SERVER_INC is ./include"
STATUS,"H_FILE is /home/lx/my-codes/C++/Others/Socket/Server/./include/Server.h"
STATUS,"SOURCE is main.cppServer.cpp/home/lx/my-codes/C++/Others/Socket/Server/./include/Server.h"
-- Configuring done
-- Generating done
-- Build files have been written to: /home/lx/my-codes/C++/Others/Socket/Server

运行make 后报错

lx@lx-virtual-machine:~/my-codes/C++/Others/Socket/Server$ make 
Scanning dependencies of target Server
[ 33%] Building CXX object CMakeFiles/Server.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/Server.dir/Server.cpp.o
[100%] Linking CXX executable Server
/usr/bin/ld: CMakeFiles/Server.dir/Server.cpp.o: in function `std::thread::thread<void (Server::*)(descript_socket), Server*, descript_socket&, void>(void (Server::*&&)(descript_socket), Server*&&, descript_socket&)':
Server.cpp:(.text._ZNSt6threadC2IM6ServerFv15descript_socketEJPS1_RS2_EvEEOT_DpOT0_[_ZNSt6threadC5IM6ServerFv15descript_socketEJPS1_RS2_EvEEOT_DpOT0_]+0x4f): undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Server.dir/build.make:99:Server] 错误 1
make[1]: *** [CMakeFiles/Makefile2:76:CMakeFiles/Server.dir/all] 错误 2
make: *** [Makefile:84:all] 错误 2

根据保错信息undefined reference to `pthread_create’ 推测和linux下pthread有关
解决方法如下:在cmake最后两段加上find_package(Threads REQUIRED)
target_link_libraries(项目名称 Threads::Threads) 如下:

cmake_minimum_required(VERSION 3.10)
project(Server)


set(SERVER_INC ./include)
message(STATUS,"SERVER_INC is ${SERVER_INC}")
include_directories(${SERVER_INC})
file(GLOB H_FILE ${SERVER_INC}/*.h)
message(STATUS,"H_FILE is ${H_FILE}")
set(SOURCE 
                main.cpp
                Server.cpp
                ${H_FILE})
message(STATUS,"SOURCE is ${SOURCE}")
add_executable(${PROJECT_NAME} ${SOURCE})   

#新增如下代码
find_package(Threads REQUIRED) 
target_link_libraries(${PROJECT_NAME} Threads::Threads)

成功运行如下

STATUS,"SERVER_INC is ./include"
STATUS,"H_FILE is /home/lx/my-codes/C++/Others/Socket/Server/./include/Server.h"
STATUS,"SOURCE is main.cppServer.cpp/home/lx/my-codes/C++/Others/Socket/Server/./include/Server.h"
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/lx/my-codes/C++/Others/Socket/Server
[ 33%] Linking CXX executable Server
[100%] Built target Server
服务端socket创建
服务端bind绑定成功
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解决linux底下cmake编译使用C++ 11标准库自带的thread报错问题 的相关文章

随机推荐

  • CentOS安装远程桌面(XRDP)

    背景 现在大部分服务端应用都是运行在Linux上的 xff0c 所以使用Linux操作系统来开发应用会方便很多 用Mac的用户请自动跳过 准环境 主机 一台 操作系统 CentOS 7 6 安装步骤 安装软件并启动 yum groupins
  • 自定义prometheus-operator中容器的参数

    简介 prometheus opertator 方便了我们在Kubernetes里面部署prometheus集群 xff0c 但是有一些底层的配置也被掩盖了 我遇到的问题就是配置文件的实时生效 xff0c 要等3分钟才可以 于是去翻了一下C
  • Gitlab全量迁移

    背景 公司研发使用的Gitlab由于服务器下架需要迁移到新的Gitlab服务器上 Gitlab官方推荐了先备份然后再恢复的方法 个人觉得这个方案不是很友好 xff0c 故采用官方的另外一种方法 xff0c 百度后发现这个方法还没有人记录 x
  • Swift使用极光推送JPush的Demo

    JPushDemo github项目地址 需要导入JPush框架 xff0c 可以使用cocoapod导入 xff0c 也可以手动导入 环境配置 配置环境可以参考极光推送的官方文档 xff1a iOS 证书设置指南 iOS SDK 集成指南
  • 拨测API接口+监控方案

    简介 在业务运维场景中 xff0c 需要对核心的API接口进行拨测 而各个接口需要传递的参数或者接口之间的依赖是比较复杂的 xff0c 通常接口之间都是通过链式请求来完成一个业务场景 常见的就是先登录 xff0c 拿到token以后 xff
  • KVM常用命令集合

    背景 曙光的一台物理服务器6240通过KVM进行虚拟化 xff0c 创建多台虚机 记录一下整个过程中常用的命令 物理服务器信息如下 操作系统 Kylin Linux Advanced Server release V10 span clas
  • 通过cfssl自签证书https证书

    背景 公司内部自建Web服务 xff0c 通过自签CA xff0c 然后签发https证书 工具地址 GitHub cloudflare cfssl CFSSL Cloudflare 39 s PKI and TLS toolkit 使用步
  • vSphere Web Client 6.5 如何上传ISO文件

    vSphere Web Client 6 5 如何上传ISO文件 xff1f 1 xff0c 先开启SSH功能 WEB登陆管理端 xff0c 选中一台主机 xff0c 配置 xff0d 安全配置文件 xff0d 服务编辑 xff0d SSH
  • linux中sed在指定字符前后添加内容

    假设文档内容如下 xff1a 1 2 3 4 5 root 64 localhost cat tmp input txt null 000011112222 test 要求 xff1a 在1111之前添加AAA 方法如下 xff1a sed
  • 解决 - Prometheus 监控Kubelet Metrics 报错"server returned HTTP status 403 Forbidden"

    简介 使用prometheus监控kubelet的时候 xff0c 报如下403的错误 xff1a 或者报401的错误 该问题的原因是webhook的授权地址使用127 0 0 1 所以其它IP发起的请求都会被拒绝 将该地址改为0 0 0
  • 为什么每次进入命令都要重新source /etc/profile 才能生效?

    span style color 999988 编辑JDK8 span span style color 0086b3 export span JAVA HOME 61 span style color dd1144 34 usr java
  • MySQL配置文件my.ini的一般设置

    mysqld 设置3306端口 port 61 3306 设置mysql的安装目录 basedir 61 D Software Package mysql 8 0 12 winx64 mysql 8 0 12 winx64 设置mysql数
  • Linux shell脚本编程时bad substitution解决办法

    首先 xff0c 我们要理解bad substitution的字面意思 xff0c 它的字面意思是 替换错误 的意思 这种错误的原因呢 xff0c 通常是我们编写脚本时 和 xff08 xff09 错误使用导致的 比如应该用 xff08 x
  • Vue中的watch 和computed 属性

    之前写过一篇关于computed计算属性的文章 xff0c 详见这里 computed 内的function只执行一次 xff0c 仅当function内涉及到Vue实例绑定的data的值的改变 xff0c function才会从新执行 x
  • Swift使用XMPPFramework做IM即时通信的Demo

    上一篇文章处理了文本中表情的替换 xff0c 现在来完成消息的发送功能吧 xff08 貌似前后并没有逻辑关系哈 xff09 首先为了测试 xff0c 我们需要下载spark工具 xff0c 它可以连接openfire搭建的后台来完成即时通信
  • P1591 阶乘数码

    题目描述 求n 中某个数码出现的次数 输入格式 第一行为 t t 10 xff0c 表示数据组数 接下来 t 行 xff0c 每行一个正整数n n 1000 和数码 a 输出格式 对于每组数据 xff0c 输出一个整数 xff0c 表示 n
  • nginx缓存命中率统计(转)

    转自 xff1a http www libertyvps com thread 275 1 1 html nginx提供了 upstream cache status这个变量来显示缓存的状态 xff0c 我们可以在配置中添加一个http头来
  • windows远程桌面连接到Linux服务器(ubuntu系统)、解决xrdp登录界面port问题、解决password failed

    一 xff1a 一般在windows系统安装ssh客户端远程连接Linux服务器 xff0c 可以很方便地传输文件 xff08 注意 xff1a 文件路径不能有小括号 xff0c 空格之类的 xff0c 不然会出现erro xff09 但如
  • linux之文件系统命令

    第一章 linux之帮助命令 第二章 linux命令行快捷键 第三章 linux之防火墙 第四章 linux之服务开机自启 第五章 linux之关机与重启 第六章 linux之环境变量 第七章 linux之目录操作命令 第八章 linux之
  • 解决linux底下cmake编译使用C++ 11标准库自带的thread报错问题

    本人在编写linux底下socket编程测试服务端时候 xff0c 发现使用std thread函数时候 xff0c cmake编译通过 xff0c make编译失败 xff0c CMakeLists txt如下 xff1a cmake m