我发现一些代码使用std :: shared_ptr在shutdown时执行任意清理.起初我认为这段代码不可行,但后来我尝试了以下内容:
#include <memory>
#include <iostream>
#include <vector>
class test {
public:
test() {
std::cout << "Test created" << std::endl;
}
~test() {
std::cout << "Test destroyed" << std::endl;
}
};
int main() {
std::cout << "At begin of main.\ncreating std::vector<std::shared_ptr<void>>"
<< std::endl;
std::vector<std::shared_ptr<void>> v;
{
std::cout << "Creating test" << std::endl;
v.push_back( std::shared_ptr<test>( new test() ) );
std::cout << "Leaving scope" << std::endl;
}
std::cout << "Leaving main" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该程序给出了输出:
At begin of main. …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试使用stl-datastructures.但是我仍然不确定何时使用哪一个以及何时使用某种组合.目前我想弄清楚,当使用时std::multimap确实有意义.据我所知,通过组合std::map和,可以轻松地构建自己的多图实现std::vector.所以当我们应该使用每个数据结构时,我都会遇到问题.
std::vector).std::multimaps背后还有很多优化技巧,以尽可能快地迭代相同的元素.也许可以优化到达正确的元素范围std::multimaps.为了尝试速度问题,我使用以下程序进行了一些简单的比较:
#include <stdint.h>
#include <iostream>
#include <map>
#include <vector>
#include <utility>
typedef std::map<uint32_t, std::vector<uint64_t> > my_mumap_t;
const uint32_t num_partitions = 100000;
const size_t num_elements = 500000;
int main() {
srand( 1337 );
std::vector<std::pair<uint32_t,uint64_t>> values;
for( size_t i = 0; i <= num_elements; ++i ) {
uint32_t key = rand() % num_partitions;
uint64_t value = rand();
values.push_back( std::make_pair( key, value ) );
}
clock_t …Run Code Online (Sandbox Code Playgroud) 我目前正在寻找git-flow,并试图弄清楚如何将它用于我参与的项目.
我查看了各种git-flow教程,我对git非常熟悉.因此,我不需要任何关于git的技巧,而是直接使用git-flow的工作流程.
情况如下:
当我重新定义一个版本(让我们称之为1.0)时,这就得到了开发的分支,这很好.现在让我说我开始研究2.0,添加新功能.当然,一旦完成,我想将它们合并到开发中.现在1.0上的修复很好,所以我们也说我生成了几个版本1.0.1,1.0.2等.所有这些也将更新开发分支,这也很好.到目前为止,麻烦,我可以独立开发2.0和1.0.x的修补程序的功能.
但是,假设某人要求1.1版本的新功能.现在我有一个问题.如果我创建一个功能分支,这将基于开发分支,它可能已经包含2.0内容,我可能不希望在1.1版本中.
有一种简单的方法,可以独立处理这些2.0和1.1的变化吗?
我已经看到了几种可能性:
在开发的最后发布位置创建一个新分支.将开发重新定位到此位置并重命名另一个开发分支.但是,此分支不包含1.0.1等的任何修补程序.
在2.0完成之前,不要合并2.0的功能.然而,在最后一刻,我将不得不将大量未合并的更改保持打开状态.如果2.0发布并且之后要求更改为1.0.x,这也无济于事.
这对git flow来说有可能吗?即,一旦新版本的工作开始甚至完成,早期版本的版本是基于什么?
我们在应用程序中有一些持久数据,从服务器查询然后存储在数据库中,以便我们可以跟踪其他信息.因为我们不想查询何时在内存中使用对象,select for update所以我们会这样做,以便阻止其他想要获取相同数据的线程.
我不知道如何select for update处理不存在的行.如果该行不存在而另一个线程尝试select for update在同一行上执行另一个线程,则该线程是否会被阻塞,直到另一个事务完成或者它是否也会得到一个空的结果集?如果它只获得一个空的结果集是否有任何方法可以阻止它,例如通过立即插入缺失的行?
编辑:
因为有一个评论,我们可能会锁定太多,这里有一些关于我们案例中具体用法的更多细节.在减少的伪代码中,我们的程序流程如下所示:
d = queue.fetch();
r = SELECT * FROM table WHERE key = d.key() FOR UPDATE;
if r.empty() then
r = get_data_from_somewhere_else();
new_r = process_stuff( r );
if Data was present then
update row to new_r
else
insert new_r
Run Code Online (Sandbox Code Playgroud)
此代码在多个线程中运行,从队列中提取的数据可能与数据库中的同一行有关(因此锁定).但是,如果多个线程正在使用需要相同行的数据,则需要对这些线程进行顺序化(顺序无关紧要).但是,如果该行不存在,则此顺序化将失败,因为我们没有获得锁定.
编辑:
现在我有以下解决方案,这对我来说似乎是一个丑陋的黑客.
select the data for update
if zero rows match then
insert some dummy data // this will block if multiple transactions try to …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试使用脚本将其他已启动命令的输出正确写入日志文件.该脚本将使用echo将其自己的消息写入日志文件,并且有一种方法可以管理来自其他程序的行.
主要的问题是,生成输出的程序是在后台启动的,所以我执行读取的函数可以写入日志文件.这可能是个问题吗?Echo总是只写一行,所以不应该很难确保原子性.但是我已经查看了谷歌,我发现没有办法确保它实际上是原子的.
这是当前的脚本:
LOG_FILE=/path/to/logfile
write_log() {
echo "$(date +%Y%m%d%H%M%S);$1" >> ${LOG_FILE}
}
write_output() {
while read data; do
write_log "Message from SUB process: [ $data ]"
done
}
write_log "Script started"
# do some stuff
call_complicated_program 2>&1 | write_output &
SUB_PID=$!
#do some more stuff
write_log "Script exiting"
wait $SUB_PID
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,脚本既可以自己编写,也可以编写重定向输出.这会导致文件中的havok吗?
我正在考虑通过gcc查看为原子操作生成的一些程序集.我尝试了以下短序列:
int x1;
int x2;
int foo;
void test()
{
__atomic_store_n( &x1, 1, __ATOMIC_SEQ_CST );
if( __atomic_load_n( &x2 ,__ATOMIC_SEQ_CST ))
return;
foo = 4;
}
Run Code Online (Sandbox Code Playgroud)
看看Herb Sutter关于代码生成的原子武器谈话,他提到X86手册要求xchg用于原子存储和简单mov的原子读取.所以我期待的是:
test():
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $1, %eax
xchg %eax, x1(%rip)
movl x2(%rip), %eax
testl %eax, %eax
setne %al
testb %al, %al
je .L2
jmp .L1
.L2:
movl $4, foo(%rip)
.L1:
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
Run Code Online (Sandbox Code Playgroud)
由于锁定 …
我有一些给定的代码在C中的堆栈上使用可变长度数组.我不能轻易地更改该代码以malloc在堆上使用ed缓冲区,因为我正在处理一些我没有动态内存操作系统支持的东西.然而,当我测试我的方法时,堆栈实际上被砸碎了(SP即将get设置为完全虚假的地址).为了弄清楚发生了什么,我看了一下程序集,我对编译器输出完全感到困惑.
我在pandaboard ES(OMAP4460 ARM处理器)上运行代码.
为了测试堆栈上的可变大小数组是如何实际编译的,我生成了一个简单的工作测试程序.然而,代码对我来说太难以理解了.
这是我不明白的:
当我编译一个简单的函数时:
int test_method(size_t i)
{
unsigned char buffer[10];
return -1;
}
Run Code Online (Sandbox Code Playgroud)
我得到一些非常简单的汇编程序代码:
80003a68 <test_method>:
80003a68: b480 push {r7} ; store frame pointer
80003a6a: b087 sub sp, #28 ; make stack frame (size 28)
80003a6c: af00 add r7, sp, #0 ; set frame pointer
80003a6e: 6078 str r0, [r7, #4]; store parameter on stack
80003a70: f04f 0300 mov.w r3, #0 ; load return value
80003a74: 4618 mov r0, r3 ; put …Run Code Online (Sandbox Code Playgroud) 我目前正在做一些模板元编程.在我的情况下,我可以处理任何"可迭代"类型,即typedef foo const_iterator以相同方式存在的任何类型.我试图使用新的C++ 11模板元编程,但是我找不到一种方法来检测是否缺少某种类型.
因为我还需要根据其他特性打开/关闭其他模板专精,我目前正在使用带有两个参数的模板,第二个是通过生成的std::enable_if.这是我目前正在做的事情:
template <typename T, typename Enable = void>
struct Foo{}; // default case is invalid
template <typename T>
struct Foo< T, typename std::enable_if<std::is_fundamental<T>::value>::type>{
void do_stuff(){ ... }
};
template<typename T>
struct exists{
static const bool value = true;
};
template<typename T>
struct Foo<T, typename std::enable_if<exists< typename T::const_iterator >::value >::type> {
void do_stuff(){ ... }
};
Run Code Online (Sandbox Code Playgroud)
没有exists帮助模板,我无法做到这样的事情.比如简单地做
template<typename T>
struct Foo<T, typename T::const_iterator> {
void do_stuff(){ ... }
};
Run Code Online (Sandbox Code Playgroud)
不起作用,因为在应该使用此专门化的情况下,实例化了无效的默认情况.
但是我 …
我只是浏览了C++ 11标准的草案,发现了以下令人费解的声明(§13.6/ 8):
对于每种类型
T,都存在表单的候选运算符函数Run Code Online (Sandbox Code Playgroud)T* operator+(T*);
如何理解指针上的"一元+"运算符?这只是正常情况下的无操作,但仍可能过载吗?或者我在这里缺少一些更深层次的观点?
我正在寻找一个良好的功能数据结构来存储空间(点)数据.数据结构应允许对已存在的点进行简单的epsilon查询.我还需要经常修改数据.这意味着点可以移动,并且应该能够在数据结构中更新.这可以使用普通的删除/添加来处理,但真正的移动可能会更快.
现在我正在考虑使用quad/oct-trees(或更高版本),因为移动部分应该很容易.然而,就平衡而言,已知四叉树更糟糕.KD-Trees可能是另一种选择,但更新似乎非常讨厌.我能找到的大多数空间数据结构实现只是程序性的,我使用的是函数式语言.
c++ ×4
c++11 ×3
assembly ×2
c ×2
gcc ×2
arm ×1
atomic ×1
bash ×1
compilation ×1
concurrency ×1
git ×1
git-flow ×1
multimap ×1
ocaml ×1
performance ×1
postgresql ×1
scripting ×1
sfinae ×1
shared-ptr ×1
sql ×1
stl ×1
type-traits ×1