标签: stdthread

std::thread 抛出“将发生资源死锁”

我有一个对象列表,每个对象都有由“更新”函数计算的成员变量。我想并行更新对象,即我想为每个对象创建一个线程来执行它的更新功能。

这是一个合理的做法吗?这可能不是一个好主意的任何原因?

下面是一个尝试执行我所描述的程序的程序,这是一个完整的程序,因此您应该能够运行它(我使用的是 VS2015)。目标是并行更新每个对象。问题是一旦更新函数完成,线程就会抛出“将发生资源死锁”异常并中止。

我哪里错了?

#include <iostream>
#include <thread>
#include <vector>
#include <algorithm>
#include <thread>
#include <mutex>
#include <chrono>

class Object 
{
public:

    Object(int sleepTime, unsigned int id)
        : m_pSleepTime(sleepTime), m_pId(id), m_pValue(0) {}

    void update()
    {
        if (!isLocked()) // if an object is not locked
        {
            // create a thread to perform it's update
            m_pThread.reset(new std::thread(&Object::_update, this));
        }
    }

    unsigned int getId()
    {
        return m_pId;
    }

    unsigned int getValue()
    {
        return m_pValue;
    }

    bool isLocked()
    {
        bool mutexStatus = m_pMutex.try_lock(); …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading stdthread

0
推荐指数
1
解决办法
1847
查看次数

c++17 std::thread join() :没有这样的过程

抱歉,标题是一个点击诱饵...解决起来并不像您想象的那么容易...这是一个真正的挑战

我遇到一个非常奇怪的问题,即 joinable() 的线程无法 join()。

我得到的错误是No such process

这不是典型的初学者两次加入线程的错误...这是一个复杂的问题,甚至可能是由内存损坏引起的...但我希望我只是错过了一些东西,我需要一个新的外部视图...我已经研究这个问题两天了。

我正在为 Linux 和 Windows 进行编译。

在 Linux 上(使用 gcc 9.1.0),它每次都能完美运行。

在 Windows 上(在我的 Linux 机器上使用 x86_64-w64-mingw32-g++ 9.2.0 并在我的 Windows 机器上运行该程序)我总是收到错误。

以下是我可以 100% 确认的内容:

  • 线程尚未加入。该线程只调用一次 join(),就会崩溃。
  • 线程不是默认构造的(它是用 new 分配的原始指针)
  • 线程正在工作(其他线程 join() 工作正常)
  • 调用 detach() 而不是 join() 会导致相同的错误
  • 不调用 join() (而是休眠一秒钟)“修复”问题
  • 父线程(创建有问题的线程的线程)与调用 join() 的线程相同
  • 无论我们是在 Debug (-ggdb -g -O0) 还是 Release (-O3) 下编译都不会改变结果(Linux 总是有效,Windows 总是失败)
  • 错误的线程是通过 lambda 函数创建的,该函数是从另一个 lambda 函数完美转发的

最后一点很可能是问题的根源,尽管我真的不明白是怎么回事。

我还知道包含线程指针的对象在 join() 之前不会被销毁。如果成功的话,我删除该指针的唯一位置是在 join() 之后。父对象被包装在一个shared_ptr 中。

指向该线程的指针也从未在其他地方使用/共享。

该代码在这里很难简化和共享,因为它是完整网络系统的一部分,并且它的所有方面都可能是问题的根源。

哦,实际的线程已正确执行,并且所有生成的网络通信都按其应有的方式工作,即使该线程无法加入。

这是重要部分的非常简化的版本,并附有解释所发生情况的注释: …

c++ windows multithreading stdthread c++17

0
推荐指数
1
解决办法
1613
查看次数

为什么std :: thread无法打开QT对话框?

我想在std :: thread中打开一个简单的QT对话框,但是在对话框打开成功后崩溃。

std::thread([&](){
    DialogWarning* dlg=new DialogWarning();
    dlg->setModal(true);
    dlg->exec();
    delete dlg;
}).detach();
Run Code Online (Sandbox Code Playgroud)

此代码有什么问题?

qt c++11 stdthread

0
推荐指数
1
解决办法
77
查看次数

将 void 指针指向的 std::thread 转换为对象 std::thread 而不是指向对象的指针

我正在寻找我所做的练习,特别是一个“线程管理器”类,它通过将线程存储在“typedef void *HANDLE;”数组中来管理线程(真的吗?哈哈)在结构 GROUP 内声明。

所以我已经让它工作了,但我看到我正在通过“reinterpret_cast”转换为“std::thread*”来转换“HANDLE”,所以“void*”。

看到后我担心:如何以及如何将其直接转换为 std::thread 对象?

我做了这个代码,例如:

#include <iostream>
#include <thread>

typedef void *HANDLE;

class thread_obj {
    public:
        void operator()(int x){
            for(int i = 0x0; i < x; i++){
                std::cout << "i = " << i << std::endl;
            }
        }
};

int main(){

    std::thread thr(thread_obj(), 0x3);
    HANDLE test = &thr;

    std::thread *p_thr = reinterpret_cast<std::thread*>(test);

    p_thr->join();

    return 0x0;
}
Run Code Online (Sandbox Code Playgroud)

这是原始代码。

如果我这样做:

std::thread p_thr = reinterpret_cast<std::thread&>(test);
Run Code Online (Sandbox Code Playgroud)

或者:

std::thread p_thr = *reinterpret_cast<std::thread*>(test);
Run Code Online (Sandbox Code Playgroud)

或者:

std::thread *temp = reinterpret_cast<std::thread*>(test);
std::thread p_thr = …
Run Code Online (Sandbox Code Playgroud)

c++ void-pointers stdthread

0
推荐指数
1
解决办法
65
查看次数

是否存在以下情况:解锁然后锁定已解锁的互斥锁是有效的,而另一个线程尝试使用 lock_guard 锁定它?

我为这个糟糕的标题道歉,只是想找人确认我没有疯。

我最近偶然发现了一些已经使用多年而没有人抱怨的代码。我调查它的原因是因为我在大量修改此代码库时遇到此错误:

pthread_mutex_lock.c:90: ___pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.
Run Code Online (Sandbox Code Playgroud)

经过一番挖掘,我发现互斥锁的使用(对我来说)非常奇怪。在本质上:

  1. 生成两个线程并与主线程分离(两个线程位于同一个 .cpp 文件中,并共享全局声明的互斥体)
  2. 根据评论,在似乎第一个被击中的线程中,互斥体被解锁,然后在循环中暂停 10us 来锁定,以“允许其他线程处理消息”
  3. 可能会第二次命中的线程(首先生成,但等待接收数据)在 switch 语句中有一个情况,该语句使用 a 锁定互斥体lock_guard

我相信这在很多方面都是未定义的行为,但我收到了一些反对意见,认为应该改变它,因为我正在努力一致且最小化地重现这个确切的错误。

我假设这是为了让互斥体首先被循环线程解锁(从解锁状态,线程还没有要lock_guard处理的数据),然后锁定,并且大部分时间都会被锁定,而lock_guard偶尔会尝试锁定,并且必须等待循环解锁它,此时它可以处理其数据,lock_guard超出范围,并且锁定返回到循环线程。

我认为导致我的错误的是;通过我的修改,线程lock_guard获取数据的速度比预期的要快,因此lock_guard触发了该情况,然后循环线程尝试解锁另一个线程互斥体。

我在寻找:

  • 确认是UB声明互斥量,然后解锁,不加锁
  • 如果循环线程在互斥锁被持有时解锁该互斥锁,则确认它是 UBlock_guard
  • 确认我对导致错误的原因的假设(我基本上已经从参考文献中知道了前两个,但想确保我没有错过一些我不知道的做事的大脑方式)
  • 也许有更好的方法来做到这一点,我认为这可以通过首先将互斥体锁定在循环之外来解决?

我搜索了代码库,互斥体只使用了 4 次,我可以看到:当它被声明时,当它被使用时,当lock_guard它被解锁时,然后被锁定,所以我的 MRE 很短,我认为它基本上有它需要的一切。演示如何使用该互斥锁:

#include <iostream>
#include <thread>
#include <mutex>
#include <unistd.h>

std::mutex data_mtx;

void lg_thread(){
  std::lock_guard<std::mutex> guard(data_mtx);

  usleep(10e6);
}

int main(int argc, char const* argv[]){
  std::thread t1(lg_thread);

  usleep(10000);

  for (int i = 0; i …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading mutex pthreads stdthread

0
推荐指数
1
解决办法
358
查看次数

线程创建C++ std :: thread时抛出异常

我正在尝试使用C++生成一些线程,std::thread但我无法让它工作.如果它有任何区别我正在使用VS 2015.它在线程创建失败(t[thread_id] = std::thread(test);).这是我的代码的相关部分:

void test() {}

void threaded_DFT(std::complex<double>* x, std::complex<double>* X, size_t N) {

std::complex<double>* tmp=(std::complex<double>*)malloc(N * sizeof *tmp);
std::thread* t=NULL;
size_t num_threads;

size_t stages = log2(N);
size_t FFT_8_stages = stages / 3;
size_t remainder_stages = stages % 3;

size_t Ns = 1;
for (size_t i=0, Ns = 1; i < FFT_8_stages; i++,Ns=pow(2,3*i))
{
    num_threads = N / 8;
    t = (std::thread*)malloc(num_threads * sizeof *t);
    if (!t)
        exit(EXIT_FAILURE);
    for (size_t thread_id = 0; thread_id < …
Run Code Online (Sandbox Code Playgroud)

c++ stdthread

-1
推荐指数
1
解决办法
376
查看次数

C++ - 处理字符串的最佳线程数

我有一个长度为N的 std::string,我想使用线程将所有长度为K 的子字符串插入到 std::set 容器中。我应该使用多少个 std::thread 或 pthread_t 对象?

考虑 N = 500,000 和 K = 3。

c++ multithreading pthreads c++11 stdthread

-4
推荐指数
1
解决办法
1006
查看次数

标签 统计

stdthread ×7

c++ ×6

multithreading ×4

c++11 ×2

pthreads ×2

c++17 ×1

mutex ×1

qt ×1

void-pointers ×1

windows ×1