小编Mik*_*ike的帖子

是否允许主线程在进入main()之前生成POSIX线程?

我有这个包含线程的对象.我希望对象的命运和线程的命运是同一个.因此构造函数创建一个线程(带pthread_create),析构函数执行操作以使线程在合理的时间内返回,然后加入线程.只要我没有使用静态存储持续时间实例化其中一个对象,这样就可以正常工作.如果我在全局或命名空间或静态类范围中实例化其中一个对象,程序编译正常(gcc 4.8.1)但在运行时立即进行段错误.使用print语句,我确定主线程甚至在segfault之前都没有进入main().有任何想法吗?

更新:还在构造函数的第一行添加了一个print语句(所以在pthread_create调用之前),甚至在segfault之前都没有打印但是构造函数确实使用了初始化列表,所以有可能导致它的原因吗?

这是构造函数:

worker::worker(size_t buffer_size):
m_head(nullptr),m_tail(nullptr),
m_buffer_A(operator new(buffer_size)),
m_buffer_B(operator new(buffer_size)),
m_next(m_buffer_A),
m_buffer_size(buffer_size),
m_pause_gate(true),
m_worker_thread([this]()->void{ thread_func(); }),
m_running(true)
{
    print("this wont get printed b4 segfault");
    scoped_lock lock(worker_lock);
    m_worker_thread.start();
    all_workers.push_back(this);
}
Run Code Online (Sandbox Code Playgroud)

和析构函数:

worker::~worker()
{
    {
        scoped_lock lock(worker_lock);
        auto w=all_workers.begin();
        while(w!=all_workers.end())
        {
            if(*w==this)
            {
                break;
            }
            ++w;
        }
        all_workers.erase(w);
    }

    {
        scoped_lock lock(m_lock);
        m_running=false;
    }

    m_sem.release();
    m_pause_gate.open();

    m_worker_thread.join();

    operator delete(m_buffer_A);
    operator delete(m_buffer_B);
}
Run Code Online (Sandbox Code Playgroud)

更新2:

好吧我明白了.我的print函数是原子的,同样cout用其他地方定义的extern命名空间作用域mutex 保护.我改为普通,cout并在ctor的开头打印.显然,在尝试访问它们之前,这些静态存储持续时间互斥体都没有被初始化.所以是的,这可能是凯西的答案.

我只是不打扰复杂的对象和静态存储持续时间.无论如何,这没什么大不了的.

c++ multithreading pthreads segmentation-fault c++11

13
推荐指数
1
解决办法
514
查看次数

将"this"指针强制转换为另一种类型并不违反严格的别名?

所以,如果我做这样的事情:

#include <ios>

using std::forward;

template<class T>
struct pod_version final{
    private:
        alignas(T) uint8_t m_data[sizeof(T)];
    public:
        pod_version()=default;
        pod_version(const pod_version&)=default;
        pod_version(pod_version&&)=default;
        ~pod_version()=default;
        pod_version& operator=(const pod_version&)=default;
        pod_version& operator=(pod_version&&)=default;

        template<class...V>void construct(V&&...v){
            new (m_data) T(forward<V>(v)...);
        }

        void destroy(){
            reinterpret_cast<T*>(m_data)->~T(); // g++: warning typed punned blah im allowed to break ur code LOL
            reinterpret_cast<T*>(this)->~T(); // g++: :D
        }
};

int main(){
    pod_version<int> x;
    x.construct(5);
    x.destroy();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

注意:"m_data"和"this"应该指向同一个地方......

gcc 4.8.1

c++ templates pointers strict-aliasing c++11

5
推荐指数
1
解决办法
293
查看次数

在 O(n) 时间内确定大小为 n 的数组中超过一半的键是否是相同的键?

您有一个已知大小为 n 的数组或键列表。未知此列表中有多少个唯一键,可能少至 0,多至 n。这些键没有特定的顺序,而且实际上也不可能如此,因为这些键没有大于或小于的概念,只有相等或不等的概念。现在,在你说哈希映射之前,我认为还有一个条件会影响这个想法:每个键的值都是私有的。您可以获得的有关该密钥的唯一信息是它是否与另一个密钥相同。所以基本上:

class key{
    private:
        T data;
        ...
    public:
        ...
        bool operator==(const key &k){return data==k.data}
        bool operator!=(const key &k){return data!=k.data}
};

key array[n];
Run Code Online (Sandbox Code Playgroud)

现在,有没有一种算法可以在线性时间内判断数组中超过一半的键是否是相同的键?如果不是,O(n*log(n)) 又如何呢?例如,假设数组只有 3 个唯一键。数组的 60% 填充有 key.data==foo、30% key.data==bar 和 10% key.data==derp 的键。该算法只需要确定超过 50% 的键属于同一类型(data==foo 的键),并返回这些键之一。

根据我的教授的说法,这可以在 O(n) 时间内完成,但他说我们只需要找到一个可以在 O(n*log(n)) 时间内完成的任务。

arrays algorithm complexity-theory compare key

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

函数仅在标题中定义时才会内联.我错过了什么吗?

使用gcc v4.8.1

如果我做:

//func.hpp

#ifndef FUNC_HPP
#define FUNC_HPP

int func(int);

#endif

//func.cpp

#include "func.hpp"

int func(int x){
    return 5*x+7;
}

//main.cpp

#include <iostream>

#include "func.hpp"

using std::cout;
using std::endl;

int main(){
    cout<<func(5)<<endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

即使是简单的功能func也不会内联.无相结合inline,extern,static,并__attribute__((always_inline))在样机和/或定义改变了这种(这些说明的一些明显的组合,导致它甚至不会编译和/或产生警告,不谈论那些).我正在使用g++ *.cpp -O3 -o rung++ *.cpp -O3 -S组装输出.当我看到装配输出时,我仍然看到call func.它似乎只有我能够正确内联函数的方法是拥有原型(可能没有必要)和头文件中函数的定义.如果标题只包含在整个程序中的一个文件中(仅main.cpp作为例子包含),它将编译并且函数将被正确内联,甚至不需要inline符.如果要将标头包含在多个文件中,则inline需要使用说明符来解决多个定义错误,这似乎是其唯一目的.该功能当然可以正确内联.

所以我的问题是:我做错了吗?我错过了什么吗?无论发生什么:

"编译器比你聪明.它知道什么时候应该比你更好地内联函数.永远不要使用C数组.总是使用std :: vector!"

- 每个其他StackOverflow用户

真?所以调用func(5)并打印结果比打印32更快?我会盲目地跟着你离开悬崖的边缘所有人都知道并且所有明智的gcc.

为了记录,上面的代码只是一个例子.我正在写一个光线跟踪器,当我将我的数学和其他实用程序类的所有代码移动到它们的头文件并使用说明inline符时,我看到了大量的性能提升.对于某些场景,字面意思快10倍.

c c++ g++ inline compiler-optimization

3
推荐指数
1
解决办法
821
查看次数