当我g++使用-Og选项编译我的C++程序时,我会看到变量<optimized out>,并且当前行有时会跳过.这种行为是期望在这个优化级别,还是我有一些问题?gcc的手册页说:
-Og
优化调试体验.-Og启用不会干扰调试的优化.它应该是标准编辑 - 编译 - 调试周期的优化级别,提供合理的优化级别,同时保持快速编译和良好的调试体验.
因此我没想到这种行为.在我的系统上,我有g ++版本4.9.2和gdb版本7.7.1.
我在http://en.cppreference.com/w/cpp/thread/condition_variable上阅读有关std :: condition_variable的内容,我不明白这一点:
即使共享变量是原子的,也必须在互斥锁下对其进行修改,以便将修改正确地发布到等待的线程.
如果未在互斥锁下修改共享原子变量,为什么没有正确发布?怎么理解这个说法?
在另一页http://en.cppreference.com/w/cpp/atomic/atomic上有一个声明似乎与第一个声明相矛盾:
如果一个线程写入原子对象而另一个线程从中读取,则行为是明确定义的(有关数据争用的详细信息,请参阅内存模型)
我在分析核心文件时使用的是真正的gdb脚本我尝试取消引用指针并获取"源代码命令文件中的错误:无法访问地址处的内存"然后我的gdb脚本停止.我想要的只是继续执行我的gdb脚本而不停止.可能吗?
这是一个测试程序和测试gdb脚本,用于演示我的问题.在这种情况下,指针具有NULL值,但在实际情况下,指针将不具有null无效值.
这是测试C程序:
#include <stdio.h>
struct my_struct {
int v1;
int v2;
};
int main()
{
my_struct *p;
printf("%d %d\n", p->v1, p->v2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是一个测试gdb脚本:
>cat analyze.gdb
p p->v1
q
Run Code Online (Sandbox Code Playgroud)
这是问题的证明(我想从gdb这里得到这个错误信息然后去处理quit命令):
>gdb -silent a.out ./core.22384 -x ./analyze.gdb
Reading symbols from /a.out...done.
[New Thread 22384]
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x0000000000400598 in main () at main.cpp:11
11 printf("%d %d\n", p->v1, p->v2);
./analyze.gdb:1: Error in sourced command file:
Cannot access memory …Run Code Online (Sandbox Code Playgroud) 我已阅读文章同步和多处理器问题,我有一个关于InterlockedCompareExchange和InterlockedExchange的问题.问题实际上是文章中的最后一个例子.它们有两个变量iValue,fValueHasBeenComputed并且在CacheComputedValue()它们中使用InterlockedExchange以下方法修改它们:
InterlockedExchange ((LONG*)&iValue, (LONG)ComputeValue()); // don't understand
InterlockedExchange ((LONG*)&fValueHasBeenComputed, TRUE); // understand
Run Code Online (Sandbox Code Playgroud)
我知道我可以InterlockedExchange用来修改,iValue但它应该只是做
iValue = ComputeValue();
Run Code Online (Sandbox Code Playgroud)
那么实际上是否需要使用InterlockedExchange来设置iValue?或者其他线程即使正确也会看到iValue iValue = ComputeValue();.我的意思是其他线程会正确地看到iValue,因为它InterlockedExchange在它之后.
还有针对Microsoft本机代码平台的基于原理的顺序内存模型.有3.1.1示例或多或少相同的代码.其中一个推荐Make y interlocked.请注意-不能同时y和x.
更新
只是为了澄清这个问题.问题是我看到了一个矛盾."同步和多处理器问题"中的示例使用两个InterlockedExchange.相反,在示例3.1.1"Basic Reodering"(我认为与第一个示例非常相似)中,Herb Sutter给出了这个推荐
"使y互锁:如果y是互锁的,那么y上没有竞赛,因为它是原子可更新的,并且x上没有竞赛,因为a - > b - > d."
.在这个草案草案中不要使用两个互锁变量(如果我是对的,他的意思是InterlockedExchange仅用于y).
在我的程序中,有一个线程(接收线程)负责接收来自TCP套接字的请求,并且有许多线程(工作线程)负责处理接收到的请求.处理完请求后,我需要通过TCP发送答案.
这是一个问题.我想在用于接收数据的同一个线程中发送TCP数据.接收数据后,此线程通常会等待新数据select().因此,一旦工作线程完成处理请求并将答案放入输出队列,它就必须通知接收线程有数据要发送.问题是我不知道如何取消等待select()以便离开等待和打电话send().
或者我是否应该仅使用另一个线程通过TCP发送数据?
更新
MSalters,Artyom谢谢你的答案!
MSalters,看了你的答案,我发现这个网站:Winsock 2 I/O方法和阅读WSAWaitForMultipleEvents().我的程序实际上必须在HP-UX和Windows上工作我最终决定使用Artyom建议的方法.
我有一个现有的算法,如果可能的话我需要稍微优化它.目前,此算法中的大量更改不是一种选择.算法与实例一起工作std::vector< std::vector<unsigned char> >.它看起来像这样:
typedef std::vector<unsigned char> internal_vector_t;
std::vector< internal_vector_t > internal_vectors;
while (fetching lots of records) {
internal_vector_t tmp;
// reads 1Mb of chars in tmp...
internal_vectors.push_back(tmp);
// some more work
}
// use this internal_vectors
Run Code Online (Sandbox Code Playgroud)
该算法internal_vectors使用push_back()在internal_vector_t的实例中插入了很多次.internal_vector_t的大多数实例的大小为1 Mb.由于internal_vectors未知的大小没有事先做过reserve().
我不理解的第一件事是当internal_vectors达到其当前容量时发生的事情,需要分配一个新块并将其当前内容复制到更大的内存块中.由于大多数块的大小都是1Mb,因此复制操作很长.我是否应该期望编译器(gcc 4.3,MS VC++ 2008)能够优化它以避免复制?
如果复制是不可避免的,会改变std::deque帮助吗?我认为std :: deque因为我仍然需要通过像internal_vectors [10]这样的索引来访问.像这样:
typedef std::vector<unsigned char> internal_vector_t;
std::deque< internal_vector_t > internal_vectors;
// the same while
Run Code Online (Sandbox Code Playgroud)
据我所知std::deque,不需要重新定位曾经分配过.我是对的,std::deque在这种情况下会重新减少分配和复制push_backs吗?
在gcc doc中给出了一个使用原因section.这个原因是to map to special hardware.但这似乎不是我的情况.
所以我已经完成了修改我们在项目中使用的共享库的任务.它是一个Linux库.库中有变量声明让我感到困惑.他们看起来像这样(大致):
static int my_var_1 __attribute__((section("STACK"))) = 0;
Run Code Online (Sandbox Code Playgroud)
__attribute__((section("STACK"))))
my_var_1 不是常数.my_var_1在初始化期间可能会在代码中更改:
my_var_1 = atoi(getenv("MY_VAR_1") ? getenv("MY_VAR_1") : "0");
Run Code Online (Sandbox Code Playgroud)
稍后在库中使用它像这样:
inline void do_something() __attribute__((always_inline));
inline void do_something()
{
if (my_var_1)
do_something_else();
}
Run Code Online (Sandbox Code Playgroud)
使用中可能有什么意义__attribute__((section("STACK")))?我明白这section告诉编译器在特定部分放置一个变量.然而,static int准确地放入"堆叠"部分可能是什么意思?
readelf -t my_lib.so
[23] .got.plt
PROGBITS 00000000002103f0 00000000000103f0 0
00000000000003a8 0000000000000008 0 8
[0000000000000003]: WRITE, ALLOC
[24] .data
PROGBITS 00000000002107a0 00000000000107a0 0
00000000000000b0 …Run Code Online (Sandbox Code Playgroud) 我在RedHat Linux 5.0提供功能的内部共享库free和malloc:
>nm ./libmem_consumption.so | grep -P -e "\bfree\b|\bmalloc\b"
0000000000006540 T free
00000000000088a0 T malloc
Run Code Online (Sandbox Code Playgroud)
此共享库负责提供有关进程内存消耗的信息.不幸的是,当它与Apache一起使用时,这个共享库存在问题httpd.当使用这个库运行Apache httpd时,我得到一个coredump in libc::free和一条指针无效的消息.问题似乎是在http.so中,这是一个由libphp5.so加载的共享库,由httpd.
实际上,当我没有加载http.so一切都没关系,没有coredump.(加载或不加载http.so由配置文件中的指令管理:extension = http.so)当我加载http.sohttpd进程coredumps时.
httpd 以这种方式推出:
LD_PRELOAD=./libmem_consumption.so ./bin/httpd -f config
Run Code Online (Sandbox Code Playgroud)
和退出时的coredumps.
当我设置LD_BIND_NOW = 1并http.so加载时,我看到(在gdb下)http.so已free@plt指向libc::free并在其他已加载的库(例如libphp5.so)中free@plt指向libmem_consumption.so::free.怎么可能呢?
顺便说一句,当我导出LD_DEBUG = all并将输出保存到文件时,我看到这些行为libphp5.so(也加载了):
25788: symbol=free; lookup in file=/apache2/bin/httpd [0]
25788: symbol=free; lookup in file=/apache2/ps/lib/libmem_consumption.so [0]
25788: binding file /apache2/modules/libphp5.so [0] …Run Code Online (Sandbox Code Playgroud) 首先,我是Redis的新手.
所以,我测量延迟redis-cli:
$ redis-cli --latency
min: 0, max: 31, avg: 0.55 (5216 samples)^C
Run Code Online (Sandbox Code Playgroud)
好的,平均而言我在0.55毫秒内得到了响应.由此我假设在1秒内只使用一个连接,我可以得到:1000ms/0.55ms =每秒1800个请求.
然后在同一台计算机上,我只redis-benchmark使用一个连接运行,每秒获得超过6000个请求:
$ redis-benchmark -q -n 100000 -c 1 -P 1
PING_INLINE: 5953.80 requests per second
PING_BULK: 6189.65 requests per second
Run Code Online (Sandbox Code Playgroud)
因此,测量延迟时,我预计每秒最多可获得2000个请求.但是我每秒得到6000个请求.我找不到解释.我计算时是否正确:1000毫秒/ 0.55毫秒=每秒1800个请求?
我需要重新编写free()func用于教育目的,它也必须命名free().
当我重命名我的功能时,myfree()它完美地工作但是当我命名它时free(),程序不知道他是否需要使用我的或系统的所以程序Segmentation fault(core dumped)即使我不调用我的自由(只是声明另一个free()功能似乎崩溃了)
那我怎么能告诉编译器使用我的而不是系统?
提前谢谢你.
编辑:Linux操作系统