我有一个Linux程序,它产生几个进程(fork)并通过POSIX共享内存进行通信.我想让每个进程分配一个id(0-255).我的目的是将一个位向量放在共享内存区域(初始化为零)并进行原子比较并交换一点来分配一个id.
是否有一个c ++ 11友好的方式来做到这一点?我可以创建一个原子位集吗?我可以跨进程使用互斥吗?我如何确保在所有进程中只调用一次构造函数?
我正在编写代码以在两个Linux机箱之间发送原始以太网帧.为了测试这个,我只想获得一个简单的客户端发送和服务器接收.
我让客户端正确地创建数据包(我可以使用数据包嗅探器看到它们).
在服务器端,我像这样初始化套接字:
fd = socket(PF_PACKET, SOCK_RAW, htons(MY_ETH_PROTOCOL));
Run Code Online (Sandbox Code Playgroud)
MY_ETH_PROTOCOL我用作ethertype的2字节常量在哪里,所以我没有听到无关的网络流量.
当我将这个套接字绑定到我的接口时,我必须在socket_addr结构中再次传递一个协议:
socket_address.sll_protocol = htons(MY_ETH_PROTOCOL);
如果我编译并运行这样的代码,那么它就会失败.我的服务器没有看到数据包.但是,如果我像这样更改代码:
socket_address.sll_protocol = htons(ETH_P_ALL);
服务器然后可以看到从客户端发送的数据包(以及许多其他数据包),所以我必须检查数据包,看它是否匹配MY_ETH_PROTOCOL.
但我不希望我的服务器听到未在指定协议上发送的流量,因此这不是解决方案.我该怎么做呢?
我写了以下c代码:
#include <stdio.h>
int main () {
printf("%d\n", -1 >> 8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用-m32标志在x86_64上使用gcc 4.6.3编译此代码.我按照我的预期打印出-1,使用二进制补码表示算术运算得到-1.
现在,如果我改写
printf("%d\n", 0xFFFFFFFF >> 8);
Run Code Online (Sandbox Code Playgroud)
我得到16777215.我本来期望这个常量被解释为一个int(有符号)然后转换为算术,这将再次导致-1.我查看了最新的C标准,我似乎无法理解为什么会这样.有任何想法吗?
我有一个线程需要将数据从内存缓冲区写入磁盘数千次.我对每次写入需要多长时间有一些要求,因为需要清除缓冲区以便单独的线程再次写入它.
我用dd测试了磁盘.我没有在其上使用任何文件系统并直接写入磁盘(使用direct标志打开它).我能够以32K块大小获得大约100 MB/s.
在我的应用程序中,我注意到我无法以接近此速度将数据写入磁盘.所以我调查了发生了什么,我发现有些写作花了很长时间.我的代码块看起来像(顺便说一句是C语言):
last = get_timestamp();
write();
now = get_timestamp();
if (longest_write < now - last)
longest_write = now - last;
Run Code Online (Sandbox Code Playgroud)
最后我打印出最长的写入.我发现对于32K缓冲区,我看到最长的写入速度约为47ms.这太长了,无法满足我的应用程序的要求.我不认为这可以完全归因于磁盘的旋转延迟.有什么想法,我可以做些什么来获得更稳定的写入速度?谢谢
编辑:我实际上使用了上面声明的类型的多个缓冲区,并将它们之间的条带化为多个磁盘.我的问题的一个解决方案是增加缓冲区的数量以分摊长写入的成本.但是,我想保持用于缓冲的内存量尽可能小,以避免弄乱产生写入缓冲区的数据的线程的缓存.我的问题应该局限于处理将小块写入磁盘的延迟的变化以及如何减少它.
我正在尝试组装一小段 x86 代码。我在 32 位机器上,我编写了以下代码。它应该只是将值添加到 eax 中然后返回。我意识到不会有任何输出。当我编译这个使用
gcc main.S -o main
它编译没有错误。但是当我运行它时会出现段错误(gdb 声称它在第一条 movl 指令上出现段错误)。main.S 中有以下代码。我究竟做错了什么?
.text
.globl main
main:
pushl %ebp
movl %esp, %ebp
movl 0, %eax
addl $3, %eax
addl $3, %eax
leave
ret
Run Code Online (Sandbox Code Playgroud) 我正在为x86_64编写中断处理例程.ABI指定在调用C函数之前,我必须将堆栈对齐到16个字节.x86_64 ISA指定在进入ISR时,我的堆栈是8字节对齐的.我需要将我的堆栈指针对齐到16个字节.问题是从我的C函数返回时,我必须恢复(可能)未对齐的堆栈指针,以便我可以正确地从我的中断返回.
我想知道是否有办法在不使用通用寄存器的情况下做到这一点?
我正在做一个只移动的等价物std::function.move_function包含指向基类的指针,move_function_base该类型会删除基础的仿函数类型.move_function_imp继承move_function_base并保存类型化的底层函子.move_function_imp定义如下:
template<class F, class ReturnType, class... ParamTypes>
class move_function_imp : public move_function_base<ReturnType, ParamTypes...> {
typename std::remove_reference<F>::type f_;
public:
virtual ReturnType callFunc(ParamTypes&&... p) override {
return f_(std::forward<ParamTypes>(p)...);
}
explicit move_function_imp(const F& f) : f_(f) {}
explicit move_function_imp(F&& f) : f_(std::move(f)) {}
move_function_imp() = delete;
move_function_imp(const move_function_imp&) = delete;
move_function_imp& operator=(const move_function_imp&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
当我使用它时,我得到一个错误,构造函数不能相互重载.我究竟做错了什么?完整代码位于此处.
编辑:从ideone链接粘贴的错误:
prog.cpp: In instantiation of ‘class move_function_imp<main()::__lambda0&, void>’:
prog.cpp:39:30: required from …Run Code Online (Sandbox Code Playgroud) 我正在编写带有一些实时约束的C代码.我测试了用dd写入磁盘的速度:
dd if =/dev/zero of =/dev/sdb bs = 32K count = 32768 oflag = direct
这会将32GB块中的1GB零写入/ dev/sdb
我达到了大约103 MB/s
现在我以编程方式执行类似的操作:
open("/dev/sdb",O_WRONLY|O_CREAT|O_DIRECT|O_TRUNC, 0666);
Run Code Online (Sandbox Code Playgroud)
我得到一个时间戳值从32K缓冲区写入/ dev/sdb 10,000次(在for循环中)得到另一个时间戳值做一些数字运算以获得以MB/s为单位的速率,它大约是49 MB/s
为什么我不能达到与dd相同的速度?一个strace显示了我使用的相同打开命令.
我试图找出定义具有恒定大小的全局数组的最佳方法,并且我得出以下选项,所有这些都有自己的缺陷.
// 1:
#define ASIZE 10
int array[ASIZE];
// 2:
enum {ASIZE = 10};
int array[ASIZE];
// 3:
#define ASIZE_DEF 10
static const int ASIZE = ASIZE_DEF;
int array[ASIZE_DEF];
Run Code Online (Sandbox Code Playgroud)
前两个问题是我无法ASIZE从GDB 获得价值.我想第三种选择是最好的,因为我仍然可以转储它的值const,但它也会在另一个宏中泄漏.我可以undef在定义数组后使用宏,const但如果#define和const它们在数组声明的单独文件中,那么它会有点毛茸茸.
有没有更好的办法?
我有下面的代码,我尝试在verilog中实现低延迟的第一个单词fall-through fifo.
reg [width-1:0] mem [depth-1:0];
always @ (posedge clk) begin
if (wr_en) begin
mem[wr_pointer[address_width-1:0]] <= #1 din;
end
end
assign #1 dout = mem[rd_pointer[address_width-1:0]];
always @ (posedge clk) begin
if (reset) begin
wr_pointer <= #1 0;
end else if (wr_en) begin
wr_pointer <= #1 wr_pointer + 1'b1;
end
end
always @ (posedge clk) begin
if (reset) begin
rd_pointer <= #1 0;
end else if (rd_en) begin
rd_pointer <= #1 rd_pointer + 1'b1;
end
end
Run Code Online (Sandbox Code Playgroud)
我合成它并收到以下消息:
INFO:Xst:3218 - HDL ADVISOR …Run Code Online (Sandbox Code Playgroud) 我正在尝试ACCESS_ONCE在c ++ 11中实现相当于Linux的宏.
ACCESS_ONCE(x)获取x的地址,强制转换为指向与x相同类型的volatile的指针,然后取消引用它.这会强制编译器不通过此宏优化对x的访问(并使访问仅在此处进行一次).
我在c ++ 11中尝试这样做涉及decltype:
#define ACCESS_ONCE(x) (*static_cast<decltype(x) volatile *>(&(x)))
Run Code Online (Sandbox Code Playgroud)
这适用于大多数情况,但我使用它一次:
void foo(void **bar) {
while (ACCESS_ONCE(*bar) != NULL)
;
}
Run Code Online (Sandbox Code Playgroud)
这失败并出现错误:
'volatile' qualifiers cannot be applied to 'void*&'
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我正在使用C语言开发一个项目,该项目要求线程运行在与初始进程不同的CPU上.我正在使用pthread库来创建这些线程.我使用sched_setaffinity将主进程固定到cpu.我可以为每个线程执行相同操作以将它们固定到单独的CPU上吗?
我也在固定主要过程的记忆.在创建pthreads之前调用mlockall(MCL_CURRENT | MCL_FUTURE)是否也会锁定pthreads使用的所有内存,或者我需要在每个pthread中再次调用它?
提前致谢.
我有一个rails应用程序,我有一个belongs_to has_many关系的集群和用户.
在cluster_controller创建方法中,我写道:
@cluster = @current_user.clusters.build(params[:cluster])
Run Code Online (Sandbox Code Playgroud)
现在我想运行一些命令行脚本:
output = `echo cluster#{@cluster.id} > /tmp/out`
Run Code Online (Sandbox Code Playgroud)
......这里有其他功能
我也试过了
output = `echo cluster#{@cluster.id.to_s} > /tmp/out`
Run Code Online (Sandbox Code Playgroud)
当我这样做时,文件只有群集而不是群集#.为什么这样,我该如何解决?