【问题标题】:Multithreading requests with queue cpp使用队列 cpp 的多线程请求
【发布时间】:2021-10-30 05:42:07
【问题描述】:

我试图在 C++ 中创建多线程代理检查器,当我启动线程并锁定它时,所有线程都等到请求完成。我试图卸下锁,但这也无济于事。我使用 cpr 库来提出请求,可以在此处找到文档:https://whoshuu.github.io/cpr/advanced-usage.html

可重现的例子:

#include <stdio.h>
#include <pthread.h>
#include <iostream>
#include <queue>
#include <mutex>
#include <cpr/cpr.h>
#include <fmt/format.h>

#define NUMT 10

using namespace std; 
using namespace fmt;

std::mutex mut;
std::queue<std::string> q;

void* Checker(void* arg) {

    while (!q.empty()) {

        mut.lock();

        //get a webhook at https://webhook.site

        string protocol = "socks4";
        string proxyformatted = format("{0}://{1}", protocol, q.front());
        
        auto r = cpr::Get(cpr::Url{ "<webhook url>" },
            cpr::Proxies{ {"http", proxyformatted}, {"https", proxyformatted} });

        q.pop();
        mut.unlock();
    }

    return NULL;
}


int main(int argc, char** argv) {

    q.push("138.201.134.206:5678");
    q.push("185.113.7.87:5678");
    q.push("5.9.16.126:5678");
    q.push("88.146.196.181:4153");

    pthread_t tid[NUMT]; int i;
    int thread_args[NUMT];


    for (i = 0; i < NUMT; i++) {
        thread_args[i] = i;
        pthread_create(&tid[i], NULL, Checker, (void*) &thread_args);
    }

    for (i = 0; i < NUMT; i++) {
        pthread_join(tid[i], NULL);
        fprintf(stderr, "Thread %d terminated\n", i);
    }

    return 0;
}

提前致谢。

【问题讨论】:

  • 有趣的是你混合了std::mutex 和 pthreads。你没有使用std::thread是有原因的吗?
  • 没试过std::thread,我试试谢谢。
  • 从多个线程对对象的非只读、非原子、非同步访问的未定义行为。
  • 使用std::thread 不会改变任何事情。即使我不知道您的问题是什么,我也可以对此充满信心。您需要清楚地说明出了什么问题。
  • 想想你想要做什么。如果互斥锁在整个事务中保持锁定状态,则多个线程毫无价值。一次只能有一个线程对队列进行操作。考虑在工作时从队列中弹出一个作业,解锁互斥锁,处理项目,然后锁定互斥锁以在作业失败时放回项目。这将允许多个线程同时工作。\

标签: c++ multithreading queue pthreads


【解决方案1】:

我建议为您的队列实现一个包装类,以隐藏互斥锁。

该类可以提供push(std::string s)bool pop(std::string&amp; s),它们返回true 并填充s,如果队列不为空或否则为假。然后你的工作线程可以简单地循环

std::string s;    
while(q.pop(s)) {
...
}

【讨论】:

  • 我建议使用if (failed) { q.push(s) } 完成答案。
  • @user4581301 听起来不错,但在原始问题中 q.pop(); 被无条件调用
  • 我反对我的反对意见。我误读了问题的描述,并假设提问者在代码中遗漏了该细节。可能我的大脑插入了额外的要求,因为我能想到的不立即弹出的唯一原因是希望将项目留在队列中,以便在失败时可以重复它。很高兴我现在没有回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 2012-12-08
  • 2023-03-08
  • 2014-07-04
  • 1970-01-01
  • 2013-10-10
  • 1970-01-01
相关资源
最近更新 更多