我正在查看一些使用 pthread 的遗留 Linux 代码。
在一个线程中,通过 fgets() 读取文件。FILE 变量是所有线程共享的全局变量。(嘿嘿,这不是我写的……)
在另一个线程中,FILE 不时关闭并使用另一个文件名重新打开。
发生这种情况后的几秒钟内,线程 fgets() 就好像它正在继续读取它从前一个文件中读取的最后一条记录:几乎好像发生了错误但 fgets() 没有返回 NULL。然后它自己整理并开始从新文件中读取。
代码看起来有点像这样(为简洁起见,所以我希望它仍然可以理解):
在一个线程中:
while(gRunState != S_EXIT){
nanosleep(&timer_delay,0);
flag = fgets(buff, sizeof(buff), gFile);
if (flag != NULL){
// do something with buff...
}
}
Run Code Online (Sandbox Code Playgroud)
在另一个线程中:
fclose(gFile);
gFile = fopen(newFileName,"r");
Run Code Online (Sandbox Code Playgroud)
没有锁定来确保 fgets() 与 fclose()/fopen() 不同时调用。
关于可能导致 fgets() 失败但不返回 NULL 的失败模式的任何想法?
我希望一个通用的可重用类能够执行回调.我通常使用虚函数来执行此操作:
通用类:
class LibraryClass
{
private:
virtual void SomeCallback(){}
};
Run Code Online (Sandbox Code Playgroud)
使用泛型类的代码:
class AppClass;
class LibraryClassWrapper: public LibraryClass
{
public:
LibraryClassWrapper(AppClass& appClass):appClass_(appClass){}
private:
virtual void SomeCallback();
AppClass& appClass_;
};
class AppClass
{
public:
AppClass():libraryClassWrapper_(*this){}
void handleCallbackFromLibraryClass()
{
std::cout << "Handling callback" << std::endl;
}
private:
LibraryClassWrapper libraryClassWrapper_;
};
void LibraryClassWrapper::SomeCallback()
{
appClass_.handleCallbackFromLibraryClass();
}
Run Code Online (Sandbox Code Playgroud)
这似乎是一个非常多的样板,只是为了连接一个回调.另一种方法是使用仿函数,它可能更清洁一些.
但在我看来,在编译时已经知道了很多.这可以简化,以便在编译时解决回调吗?
考虑这个小例子:
#include <iostream>
struct A
{
void foo()
{
std::cout << "A::foo" << std::endl;
}
};
struct B
{
void foo()
{
std::cout << "B::foo" << std::endl;
}
};
struct C:private A
{
using A::foo;
};
struct D:private B, public C
{
};
int main()
{
D myD;
myD.foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用g ++ 4.8.1编译此示例时,我收到以下错误:
prog.cpp: In function ‘int main()’:
prog.cpp:32:9: error: request for member ‘foo’ is ambiguous
myD.foo();
^
prog.cpp:5:10: note: candidates are: void A::foo()
void foo()
^
prog.cpp:5:10: …Run Code Online (Sandbox Code Playgroud) 在c ++ 11中,将'override'说明符添加到派生类中的虚方法中,声明了覆盖基类中的虚函数的意图.
有没有办法在C++ 03中实现类似的效果,假设它只能修改派生类而不是基类?
iostream对象cin,cout,cerr和clog是iostream头中声明的对象.
我知道在一些编译器中可能会在构造它们之前尝试使用这些iostream对象,所以在某些情况下它们必须受到"静态初始化顺序惨败"的影响.在那些使用std :: cout等人总是安全的编译器中,这些对象如何实际构建?它是否涉及引擎盖下的编译器魔法,或者它原则上是否都可以用标准C++完成?
std :: cout等似乎是全局变量或单例:为什么全局变量和单例通常被认为是邪恶的,但在这种特殊情况下似乎不是?
我有一个std ::对象的映射,其实例构造起来非常昂贵.(在现实生活中,他们需要多次访问数据库.)
我想访问地图的一个元素,或者如果它不存在则创建它.这听起来像std :: map :: insert的工作,除了昂贵的对象不必要地构造,然后如果元素存在则抛弃.为了显示:
#include <iostream>
#include <map>
#include <string>
struct CexpensiveObject
{
CexpensiveObject(const char* args="default"):args_(args)
{
std::cout << "Constructor: CexpensiveObject(" << args << ")" << std::endl;
}
CexpensiveObject( const CexpensiveObject& other )
{
std::cout << "Copy Constructor: CexpensiveObject other.args_ = " << other.args_ << "." << std::endl;
args_ = other.args_;
}
~CexpensiveObject()
{
std::cout << "Destructor: CexpensiveObject args_ = " << args_ << "." << std::endl;
}
const char* args_;
};
// entry point
int main() …Run Code Online (Sandbox Code Playgroud) 考虑这个简短的代码片段,其中一个 boost::deadline_timer 中断了另一个:
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/asio.hpp>
static boost::asio::io_service io;
boost::asio::deadline_timer timer1(io);
boost::asio::deadline_timer timer2(io);
static void timer1_handler1(const boost::system::error_code& error)
{
std::cout << __PRETTY_FUNCTION__ << " time:" << time(0) << " error:" << error.message() << " expect:Operation canceled." << std::endl;
}
static void timer1_handler2(const boost::system::error_code& error)
{
std::cout << __PRETTY_FUNCTION__ << " time:" << time(0) << " error:" << error.message() << " expect:success." << std::endl;
}
static void timer2_handler1(const boost::system::error_code& error)
{
std::cout << __PRETTY_FUNCTION__ << " …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一些目前看起来像这样的Python代码:
if validator("foo", "bar"):
self.a = accessor("foo", "bar")
if validator("xxx", "yyy"):
self.b = accessor("xxx", "yyy")
Run Code Online (Sandbox Code Playgroud)
这都包含在类方法中,self.a和self.b是实例变量.
我想避免所有这些重复的validator()和accessor()的参数.如果python有pass-by-reference,我会做这样的事情:
def validate_and_access(self, target_ref, parm1, parm2)
if validator(parm1, parm2):
target_ref = accessor(parm1, parm2)
Run Code Online (Sandbox Code Playgroud)
鉴于我没有传递参考,还有另一种方法吗?我考虑使用getattr()通过名称作为字符串访问实例变量,或者甚至可能定义包含实例变量的字典,但这两者看起来都有点过分而且相当笨重.
c++ ×6
boost ×1
boost-asio ×1
c ×1
c++03 ×1
c++11 ×1
inheritance ×1
iostream ×1
linux ×1
pthreads ×1
python ×1
python-2.7 ×1