我正在寻找C或C++中的这个问题的解决方案.
编辑:澄清.这是在Linux系统上.特定于Linux的解决方案绝对没问题.跨平台不是一个问题.
我有一个在自己的线程中运行的服务.这个服务是一个有几个方法的类,其中一些方法需要在自己服务的线程中而不是在调用者的线程中运行.
目前我正在使用包装器方法创建具有输入和输出参数的结构,将结构插入队列并返回(如果"命令"是异步的)或等待其执行(如果"命令"是同步的).
在线程方面,服务唤醒,从队列中弹出一个结构,找出要执行的内容并调用适当的方法.
这个实现有效,但添加新方法非常麻烦:定义包装器,带参数的结构和处理程序.我想知道是否有一种更简单的方法来编写这种模型:一种类方法,它在类自己的线程上执行,而不是在调用者的线程中执行.
编辑 - 一种结论:
似乎没有事实上的方法来实现我所要求的,不涉及额外的编码工作.
我会坚持我提出的方法,它确保类型安全,最小化锁定,允许同步和异步调用以及相当适度的开销.
另一方面,它需要一些额外的编码,并且随着方法数量的增加,调度机制可能变得臃肿.在构造上注册调度方法,或者让包装器执行该工作似乎可以解决问题,消除一些开销并删除一些代码.
我正在考虑使用可能数百个线程来实现通过网络管理设备的任务.
这是一个在带有Linux内核的powerpc处理器上运行的C++应用程序.
在每个任务执行同步以将数据从设备复制到任务的初始阶段之后,任务变为空闲,并且仅在收到警报时唤醒,或者需要更改某些数据(配置),这在启动后很少见相.一旦所有任务都达到"空闲"阶段,我预计每秒只需要唤醒几次.
所以,我主要担心的是,如果我有数百个线程,它们会在闲置后对系统产生负面影响吗?
谢谢.AMSO
编辑:
我正在根据我得到的答案更新问题.多谢你们.因此,似乎拥有大量线程空闲(IO阻塞,等待,休眠等)本身在响应性方面不会对系统产生影响.当然,他们会为每个线程的堆栈和TLS数据花费额外的钱,但只要我们在该东西上投入更多内存(使其更多),这是可以的.
但是,其他问题必须考虑在内.由于需要等待队列或其他类似资源,等待100个线程可能会增加内核的内存使用量.还有一个延迟问题,看起来不确定.要检查每个解决方案的响应能力和内存使用情况,应该对其进行测量并进行比较.
最后,数百个主要是空闲的线程的整个想法可以像线程池一样建模.这减少了一点代码线性,但显着提高了解决方案的可扩展性,并且可以轻松调整propper care,以调整性能和资源使用之间的折衷.
我认为就是这样.感谢大家的投入.
-
amso
在我的项目中,我有一个"架构"文件和实用程序,我写了生成头文件.我正在使用cmake和源代码构建来构建应用程序.
目前我必须手动重新生成头文件然后构建应用程序.
然后我想出了这个CMakeLists.txt语句,但是它们在构建目录中而不是在源目录中生成头.
configure_file( generator.pl generator COPYONLY )
configure_file( schema.txt.in schema.txt COPYONLY )
add_custom_command(
OUTPUT generated.h
COMMAND ./generator schema.txt generated.h
DEPENDS mib_schema.txt.in generator.pl
COMMENT "Regenerating header file..."
)
Run Code Online (Sandbox Code Playgroud)
是否可以在源目录中生成标头?
编辑(以反映答案):
通过使用其中任何一个完全限定其路径,可以直接访问该文件
${CMAKE_CURRENT_SOURCE_DIR}
Run Code Online (Sandbox Code Playgroud)
要么:
${CMAKE_CURRENT_BINARY_DIR}
Run Code Online (Sandbox Code Playgroud)
因此,要在我的源目录中生成标题,之前从CMakeLists.txt中摘录的内容将变为:
add_custom_command(
OUTPUT generated.h
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/generator.pl ${CMAKE_CURRENT_SOURCE_DIR}/schema.txt.in ${CMAKE_CURRENT_SOURCE_DIR}/generated.h
DEPENDS mib_schema.txt.in generator.pl
COMMENT "Regenerating header file..."
)
Run Code Online (Sandbox Code Playgroud)
这实际上更简单.谢谢
- 至
AFAIK短路评估意味着仅在我们可以保证其结果的点上评估布尔表达式.
这是perl中常见的习惯用法,我们可以编写如下内容:(is_ok()在"OK"上返回非零值)
is_ok() || die "It's not OK!!\n";
Run Code Online (Sandbox Code Playgroud)
代替
if ( ! is_ok() ) {
die "It's not OK!!\n";
}
Run Code Online (Sandbox Code Playgroud)
这只能起作用,因为评估的顺序始终是从左到右,并且只保证最右边的语句只在第一个语句不是"false"时执行.
在CI中可以做类似的事情:
struct foo {
int some_flag;
} *ptr = 0;
/* do some work that may change value of ptr */
if ( 0!=ptr && ptr->some_flag ) {
/* do something */
}
Run Code Online (Sandbox Code Playgroud)
使用这种成语是否安全?
或者,ptr->some_flag
在确保ptr不是零指针之前,编译器是否有可能生成评估代码?(我假设如果它是非null,则指向一些有效的内存区域).
这种语法使用起来很方便,因为它可以节省输入而不会失去可读性(我认为无论如何).但是我不确定它是否完全安全,这就是为什么我想了解更多.
注意:如果编译器对此有影响,我使用的是gcc 4.x.