C++11 线程段错误

标签 c++ multithreading c++11 thread-safety mutex

现在我正在学习 C++ 多线程。我写了一个简单的代理检查器。但我不知道如何解决我遇到的问题:

我想我需要使用 std::mutex。但是我找不到它可以工作的地方。

.h:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <thread>
#include <deque>
#include <utility>
#include <mutex>

#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>

class ProxyChecker
{
public:
    ProxyChecker();
    ~ProxyChecker();

    bool check_proxy(std::string&, int&);

    void parse_file();
    void print_list();
    void parse_list();

private:
    std::mutex                               m_mutex;
    std::string                              file_name = "./vipsocks.txt";
    std::deque<std::pair<std::string, int>>  proxy_list;

    std::vector<std::thread>                 threads;
};

.cpp:

#include "proxy_checker.h"

ProxyChecker::ProxyChecker()
{
    this->parse_file();  
    this->print_list();

    try {
        for(int i = 0; i < 10; i++) {
            threads.push_back(std::thread(&ProxyChecker::parse_list, this));
        }

        for(int i = 0; i < 10; i++) {
            threads[i].join();
        }

    } catch(const std::exception &ex) {
        std::cout << ex.what() << std::endl;
    }
}

ProxyChecker::~ProxyChecker()
{

}

void ProxyChecker::print_list()
{
    for(auto it : proxy_list) {
        std::cout << it.first << ":" << it.second << std::endl;
    }

    std::cout << std::endl;
}

void ProxyChecker::parse_file()
{
    std::cout << "[FILE PARSING]" << std::endl;

    std::fstream fin(this->file_name);
    std::string  token;
    std::string  sep(":");

    while(getline(fin, token)){
        std::string::size_type pos = token.find(sep);
        std::string ip             = token.substr(0, pos);
        int port                   = std::stoi(token.substr(pos + sep.length()));        

        if((ip != "") && (port > 0)) {
            this->proxy_list.push_back(std::pair<std::string, int>(ip, port));
        }
    }
    fin.close();

    std::cout << std::endl << "[FILE PARSED]" << std::endl << std::endl;
}

void ProxyChecker::parse_list()
{
    while(!this->proxy_list.empty()) {
        if(check_proxy(proxy_list.front().first, proxy_list.front().second) == true) {
            std::cout << "[IP]: " << proxy_list.front().first << " [PORT]: " << proxy_list.front().second << " ";
            std::cout << "[SIZE]: " << proxy_list.size() << std::endl;
        }

        proxy_list.pop_front();
    }
}

bool ProxyChecker::check_proxy(std::string &ip, int &port)
{
    std::stringstream os;

    try {
        curlpp::Cleanup m_cleanup;
        curlpp::Easy    m_request;

        m_request.setOpt(curlpp::Options::Url("http://goole.com"));
        m_request.setOpt(curlpp::Options::Proxy(ip));
        m_request.setOpt(curlpp::Options::ProxyPort(port));
        m_request.setOpt(curlpp::Options::WriteStream(&os));
        m_request.setOpt(curlpp::Options::Timeout(10));

        m_request.perform();

    } catch(curlpp::RuntimeError & e) {
        std::cout << e.what() << std::endl;

        return false;
    } catch(curlpp::LogicError & e) {
        std::cout << e.what() << std::endl;

        return false;
    }

    return true;
}

拜托,你能告诉我我的代码有什么问题吗?

程序运行时出现错误:

> [IP]: 118.139.178.67 [PORT]: 24353 [SIZE]: 12 Operation timed out
> after 10000 milliseconds with 0 bytes received Operation timed out
> after 10000 milliseconds with 0 bytes received Operation timed out
> after 10001 milliseconds with 0 bytes received Operation timed out
> after 10001 milliseconds with 0 bytes received Operation timed out
> after 10001 milliseconds with 0 bytes received Operation timed out
> after 10001 milliseconds with 0 bytes received Operation timed out
> after 10000 milliseconds with 0 bytes receivedOperation timed out
> after 10000 milliseconds with 0 bytes received Operation timed out
> after 10000 milliseconds with 0 bytes received Failed to connect to
> 118.190.137.100 port 12345: Connection refused [IP]: 138.210.210.107 [PORT]: 37080 [SIZE]: 1 [IP]:  [PORT]: 0 [SIZE]: 0 [IP]:  [PORT]: 0
> [SIZE]: 18446744073709551615 [IP]:  [PORT]: [IP]: 0  [PORT]: [SIZE]: 0
> [SIZE]: 1844674407370955161418446744073709551614 [IP]:  [PORT]: 0
> [SIZE]: 18446744073709551612 [IP]:  [PORT]: 0 [SIZE]:
> 18446744073709551611 [IP]:  [PORT]: 0 [SIZE]: 18446744073709551610
> [IP]:  [PORT]: 0 [SIZE]: 18446744073709551609 [IP]:  [PORT]: 0 [SIZE]:
> 18446744073709551608 [IP]:  [PORT]: 0 [SIZE]: 18446744073709551607
> [IP]:  [PORT]: 0 [SIZE]: 18446744073709551606 [IP]:  [PORT]: 0 [SIZE]:
> 18446744073709551605 Ошибка сегментирования (стек памяти сброшен на
> диск)

最佳答案

使用互斥锁,您必须保护多个线程访问的变量,并且不是线程安全的

在你的情况下,这将是 proxy_list,它是 std::vector,它不是线程安全的(还有 std::strings并且其中的 int 不是线程安全的)。更改仅在 parse_list() 中完成。这是代码:

void ProxyChecker::parse_list()
{
    std::string proxy_str;
    int proxy_int;
    size_t list_size;
    while(true) {
        {
            std::lock_guard lock(m_mutex);
            if(proxy_list.empty())
                return;
            proxy_str = proxy_list.front().first;
            proxy_int = proxy_list.front().second;
            list_size = proxy_list.size();
            proxy_list.pop_front();
        }
        if(check_proxy(proxy_str, proxy_int) == true) {
            std::cout << "[IP]: " << proxy_str << " [PORT]: " << proxy_int << " ";
            std::cout << "[SIZE]: " << list_size << std::endl;
        }
    }
}

这里重要的是,互斥锁仅在读取/更改 proxy_list 时被锁定。 Mutex 在 check_proxy() 调用期间不能被锁定,因为它的执行时间最长,其他线程将等待,而只有一个正在运行,从而使整个程序顺序执行。

关于C++11 线程段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49348484/

相关文章:

c++ - Linux 程序员新手 -- 尝试开发库

c++ - 结构中的模板结构问题 -

java - 有效地使用 UncaughtExceptionHandler

c++ - 如何确定其他线程是否正在运行?

templates - C++11 中迭代器的类型别名/using 声明

c++ - 共享内存中彼得森锁的问题

c++ - Mongo C++ 驱动程序 - 如何更改超时配置

java - Java 控制台挂起的原因

c++ - 链接器错误:无法解析构造函数

c++ - 使用受限函数时的尾随返回类型问题