单身类的通常模式就像
static Foo &getInst()
{
static Foo *inst = NULL;
if(inst == NULL)
inst = new Foo(...);
return *inst;
}
Run Code Online (Sandbox Code Playgroud)
但是,我的理解是这个解决方案不是线程安全的,因为1)Foo的构造函数可能被多次调用(可能或可能不重要)和2)inst在返回到不同的线程之前可能没有完全构造.
一种解决方案是围绕整个方法包装一个互斥锁,但是在我真正需要它之后很长时间我就要付出同步开销.另一种选择是
static Foo &getInst()
{
static Foo *inst = NULL;
if(inst == NULL)
{
pthread_mutex_lock(&mutex);
if(inst == NULL)
inst = new Foo(...);
pthread_mutex_unlock(&mutex);
}
return *inst;
}
Run Code Online (Sandbox Code Playgroud)
这是正确的做法,还是我应该注意哪些陷阱?例如,是否存在可能发生的静态初始化顺序问题,即在第一次调用getInst时,inst总是保证为NULL?
我正在研究对性能至关重要的科学代码.该代码的初始版本已经编写和测试,现在,有了分析器,现在是时候从热点开始剃须周期了.
众所周知,编译器现在可以更有效地处理一些优化,例如循环展开,而不是手工编程的程序员.哪些技术还值得?显然,我会通过一个分析器来运行我尝试的所有内容,但是如果有传统的智慧关于什么往往有效,哪些无效,这将为我节省大量时间.
我知道优化非常依赖于编译器和体系结构.我正在使用针对Core 2 Duo的英特尔C++编译器,但我也对gcc或"任何现代编译器"的效果感兴趣.
以下是我正在考虑的一些具体想法:
std::priority_queue
),其操作占用了大量的总时间.这是值得研究的事情,还是STL实施可能是最快的?std::vector
需要大小未知但上限相当小的s,用静态分配的数组替换它们是否有利可图?最后,将某些类型的答案扼杀在萌芽状态:
我正在尝试调试一个使用MinGW的gcc编译的Windows程序,它只能在 gdb 之外运行时遇到段错误(可能是一些竞争条件......可爱.)问题是,当程序崩溃并且我没有运行GDB时,我无法获得堆栈跟踪...我可以选择在MSVC崩溃时打开程序,但是MSVC无法读取gcc的调试符号,因此它给我的堆栈跟踪是没用的.
有没有办法让Windows创建一个核心转储,然后我可以在MinGW的gdb中打开?或者,有没有办法获取MSVC的堆栈跟踪(具有原始地址但没有符号)并使用gcc来获取人类可读的跟踪?
我有非平凡度(4+)的多项式,需要鲁棒有效地确定它们是否在区间[0,T]中有根.根的确切位置或数量与我无关,我只需要知道是否至少有一个.
现在我正在使用区间运算作为快速检查,看看我是否可以证明没有根可以存在.如果我不能,我正在使用Jenkins-Traub来解决所有多项式根.这显然是低效的,因为它检查所有真正的根并找到它们的确切位置,这些信息我最终不需要.
我应该使用标准算法吗?如果没有,在完成所有根的完整Jenkins-Traub求解之前,我还能做任何其他有效的检查吗?
例如,我可以做的一个优化是检查我的多项式f(t)在0和T处是否具有相同的符号.如果不是,则在该区间中显然存在根.如果是这样,我可以求解f'(t)的根,并在区间[0,T]中的f'的所有根处求f.当且仅当所有这些评估具有与f(0)和f(T)相同的符号时,f(t)在该区间中没有根.这减少了我必须根找到的多项式的次数.不是一个巨大的优化,但也许比没有好.
我有一个需要将数据传递给低优先级进程的高优先级进程.我写了一个基本的环形缓冲区来处理数据的传递:
class RingBuffer {
public:
RingBuffer(int size);
~RingBuffer();
int count() {return (size + end - start) % size;}
void write(char *data, int bytes) {
// some work that uses only buffer and end
end = (end + bytes) % size;
}
void read(char *data, int bytes) {
// some work that uses only buffer and start
start = (start + bytes) % size;
}
private:
char *buffer;
const int size;
int start, end;
};
Run Code Online (Sandbox Code Playgroud)
这是问题所在.假设低优先级进程有一个oracle,它确切地告诉它需要读取多少数据,因此count()
永远不需要调用.然后(除非我遗漏了什么)没有并发问题.但是,只要低优先级线程需要调用count()
(高优先级线程可能也想调用它来检查缓冲区是否太满),count()或更新中的数学可能会结束不是原子的,引入了一个bug.
我可以在访问周围放置一个互斥体来开始和结束但如果高优先级线程必须等待低优先级线程获取的锁定,那么这将导致优先级倒置. …
我正在查看以下形式的代码:
class foo
{
public:
foo() {}
//...
};
class bar
{
public:
bar() : ref() {}
private:
const foo &ref;
};
Run Code Online (Sandbox Code Playgroud)
是否正确使用临时初始化引用?我知道有可能初始化一个带有临时变量的局部变量的const引用,这样做可以延长临时变量的生命周期,例如:
const foo &tmp = funcThatReturnsByValue(); //OK
Run Code Online (Sandbox Code Playgroud)
但是,初始化列表中相关初始化引用的答案之一表明"短期"和"长期"引用之间存在差异,并且ref
如上所述初始化是未定义的行为(即使ref
是const
引用).
标准中的12.2.5部分地说,"在构造函数的ctor-initializer中临时绑定到引用成员,直到构造函数退出为止." 这是描述这种情况吗?
该标准很明确:当对小于int
的整数类型执行算术运算时,该整数会首先提升为有符号int
,除非int
不能代表原始类型的完整值范围,在这种情况下,提升为unsigned int
。
我的问题是:这项政策的动机是什么?为什么将无符号类型提升为有符号类型int
,而不是总是unsigned int
?
当然,实际上,几乎没有什么区别,因为底层的汇编指令是相同的(只是零扩展),但是存在提升为的关键缺点signed int
,而没有明显的好处,因为溢出是有符号算术中的UB,但是-用无符号算术定义。
有历史原因更喜欢签字int
吗?是否存在不使用二进制补码算法的体系结构,而是将小的无符号类型提升为带符号int
而不是unsigned int
更容易/更快?
编辑:我认为这很明显,但是我在这里寻找事实(即解释设计决策的一些文档或参考资料),而不是“主要基于意见”的推测。
我试图使用以下代码在OpenGL中渲染一个二维半平面:
void renderHalfplane(double *x, double *n)
{
glPushMatrix();
double theta = -360.0 * atan2(n[0], n[1])/(2.0*PI);
glTranslated(x[0], x[1], 0);
glRotated(theta, 0, 0, 1.0);
glBegin(GL_TRIANGLES);
glVertex4d(0.0, 0.0, 0.0, 1.0);
glVertex4d(1.0, 0.0, 0.0, 0.0);
glVertex4d(0.0,-1.0, 0.0, 0.0);
glVertex4d(0.0, 0.0, 0.0, 1,0);
glVertex4d(-1.0,0.0, 0.0, 0.0);
glVertex4d(0.0,-1.0, 0.0, 0.0);
glEnd();
glPopMatrix();
}
Run Code Online (Sandbox Code Playgroud)
在这里,我使用齐次坐标在"无限远"处绘制具有两个顶点的三角形.
这段代码在我的计算机上就像一个魅力,但是用户报告说它在他们的计算机上没有正确呈现:而不是无限的半平面,他们看到两个(有限的)三角形.
我使用w坐标0未定义的行为?它只适用于某些版本的OpenGL吗?我尝试查看Khronos OpenGL规范,但找不到一个部分,其中解析了具有w坐标0的基元的渲染.
我正在尝试调试的第三方Python 2.5脚本让我陷入困境.脚本的相关部分是:
proc = subprocess.Popen(
"ls && source houdini_setup",
shell = True,
executable = "/bin/bash",
)
Run Code Online (Sandbox Code Playgroud)
有一个守护进程侦听端口5001并运行上面的脚本.脚本运行时,它会失败,并显示以下错误:
_cygwin.py
houdini_setup
... (more files) ...
/bin/sh: line 0: source: houdini_setup: file not found
Run Code Online (Sandbox Code Playgroud)
很多文件houdini_setup存在,如ls所示,实际上如果我在上面的脚本中将"source"更改为"cat",脚本会按预期打印houdini_setup的内容.此外,在一个真正的bash shell中运行上面的命令也可以在没有任何投诉的情况下获取文件.
有谁知道这里发生了什么?
我正在使用Qt进行项目.它有一些QGLWidgets,这些工作很漂亮.
问题是,我有一些遗留代码我想使用它使用原始OpenGL命令来做一些纹理和网格处理(渲染网格到图像等).我想从我的Qt代码中调用这些函数,但当然这要求我在调用OpenGL命令之前设置一个新的OpenGL上下文.
我试着做以下事情:
QGLContext context(QGLFormat::defaultFormat());
std::cout << "context creation: " << context.create() << std::endl;
if(!context.isValid())
{
std::cout << "Cannot create GL context" << std::endl;
return false;
}
context.makeCurrent();
callLegacyOpenGLCode();
Run Code Online (Sandbox Code Playgroud)
但它不起作用.QGLContext :: create()返回false.这是在Windows 7上使用Qt 4.8,使用OpenGL支持编译.
请问Qt为我创建一个新的OpenGL上下文是错误的方法吗?我该怎么做呢?
我有以下源文件:
//test1.cpp
#include <iostream>
using namespace std;
inline void foo()
{
cout << "test1's foo" << endl;
}
void bar();
int main(int argc, char *argv[])
{
foo();
bar();
}
Run Code Online (Sandbox Code Playgroud)
和
//test2.cpp
#include <iostream>
using namespace std;
inline void foo()
{
cout << "test2's foo" << endl;
}
void bar()
{
foo();
}
Run Code Online (Sandbox Code Playgroud)
输出:
test1's foo
test1's foo
Run Code Online (Sandbox Code Playgroud)
咦??? 好的,所以我应该声明foos是静态的...但是这种事情不应该产生链接器错误,或者至少是警告?编译器如何从编译单元"看到"内联函数?
编辑:这是使用gcc 4.4.1.
我得到了以下代码:
class FibHeapNode
{
//...
// These all have trivial implementation
virtual void operator =(FibHeapNode& RHS);
virtual int operator ==(FibHeapNode& RHS);
virtual int operator <(FibHeapNode& RHS);
};
class Event : public FibHeapNode
{
// These have nontrivial implementation
virtual void operator=(FibHeapNode& RHS);
virtual int operator==(FibHeapNode& RHS);
virtual int operator<(FibHeapNode& RHS);
};
class FibHeap
{
//...
int DecreaseKey(FibHeapNode *theNode, FibHeapNode& NewKey)
{
FibHeapNode *theParent;
// Some code
if (theParent != NULL && *theNode < *theParent)
{
//...
}
//...
return 1; …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个简单的nD-vector类,但遇到了一个奇怪的bug.我已经将课程剥离到最低限度,仍然可以重现该错误:
#include <iostream>
using namespace std;
template<unsigned int size> class nvector
{
public:
nvector() {data_ = new double[size];}
~nvector() {delete[] data_;}
template<unsigned int size2>
nvector(const nvector<size2> &other)
{
data_ = new double[size];
int i=0;
for(; i<size && i < size2; i++)
data_[i] = other[i];
for(; i<size; i++)
data_[i] = 0;
}
double &operator[](int i) {return data_[i];}
const double&operator[](int i) const {return data_[i];}
private:
const nvector<size> &operator=(const nvector<size> &other); //Intentionally unimplemented for now
double *data_;
};
int main()
{
nvector<2> vector2d; …
Run Code Online (Sandbox Code Playgroud)