C++方法允许const限定符指示该方法不更改对象.但是,这是什么意思?例如.如果实例变量是指针,它是指意味着指针没有改变,还是它们指向的内存没有改变?
具体来说,这是一个最小的示例类
class myclass {
int * data;
myclass() {
data = new int[10];
}
~myclass() {
delete [] data;
}
void set(const int index) const {
data[index] = 1;
}
};
Run Code Online (Sandbox Code Playgroud)
该方法set是否正确符合条件const?它不会更改成员变量data,但确实会更改数组的内容.
有没有办法有效地迭代在Python 2和Python 3中都有效的字典中的值/项?
在Python 2中,我可以写
for x in mydict:
for x in mydict.iterkeys():
for x in mydict.viewkeys():
for x in mydict.itervalues():
for x in mydict.viewvalues():
for x in mydict.iteritems():
for x in mydict.viewitems():
Run Code Online (Sandbox Code Playgroud)
在Python 3中,我有以下可能性:
for x in mydict:
for x in mydict.keys():
for x in mydict.values():
for x in mydict.items():
Run Code Online (Sandbox Code Playgroud)
所以,我可以迭代密钥for x in mydict,并且在Python 2和3中都有效.但是有没有办法迭代普遍适用的值和键值对('items')?我需要它来编写可以在两个Python版本中运行的Python代码.
(另一方面,可以轻松绕过迭代器的其他障碍;例如:
if sys.version_info.major<3:
from itertools import izip as zip, imap as map
Run Code Online (Sandbox Code Playgroud)
然而,词典的方法不容易被重新定义一样map和zip.)
有任何想法吗?
我正在为Python编写一个C扩展,它应该在对数据进行操作时释放全局解释器锁.我认为我已经很好地理解了GIL的机制,但仍然存在一个问题:当线程不拥有GIL时,我可以访问Python对象中的数据吗?例如,我想从C函数中的(大)NumPy数组中读取数据,而我仍然希望允许其他线程在其他CPU内核上执行其他操作.C函数应该
Py_BEGIN_ALLOW_THREADSPy_END_ALLOW_THREADS这样安全吗?当然,其他线程不应该改变C函数使用的变量.但也许有一个隐藏的错误来源:Python解释器可以移动一个对象,例如.通过某种垃圾收集,而C函数在一个单独的线程中工作?
为了用最小的例子说明问题,请考虑下面的(最小但完整的)代码.用它编译它(在Linux上)
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -fPIC -I/usr/lib/pymodules/python2.7/numpy/core/include -I/usr/include/python2.7 -c gilexample.c -o gilexample.o
gcc -pthread -shared gilexample.o -o gilexample.so
Run Code Online (Sandbox Code Playgroud)
用Python测试它
import gilexample
gilexample.sum([1,2,3])
Run Code Online (Sandbox Code Playgroud)
是之间的代码Py_BEGIN_ALLOW_THREADS和Py_END_ALLOW_THREADS安全吗?它访问Python对象的内容,我不想在内存中复制(可能很大)数组.
#include <Python.h>
#include <numpy/arrayobject.h>
// The relevant function
static PyObject * sum(PyObject * const self, PyObject * const args) {
PyObject * X;
PyArg_ParseTuple(args, "O", &X);
PyObject const * const X_double = PyArray_FROM_OTF(X, NPY_DOUBLE, NPY_ALIGNED);
npy_intp const size = PyArray_SIZE(X_double);
double * const …Run Code Online (Sandbox Code Playgroud) 有没有办法(在Linux中)确定哪些库必须链接到C/C++程序?即使在程序启动时未检测到未定义符号的情况下,我也不想错过库.另外,我当然希望避免不必要的依赖.
我总体上提出了这个问题,但这里有一个特别的,非常重要的例子:直到最近,我认为我需要链接libpython用于使用Boost.Python开发的Python模块.但是,事实并非如此:使用Boost.Python编写模块; 它甚至可能使用Python C API中的函数,而不仅仅是Boost.Python.链接libboost_python就足够了!这根本不是很明显 - 我至少没有找到它的文档,而且还有Boost.Python模块,它们不必要地链接到libpython.此外,这很难检测,因为libboost_python.so没有将libpython列为依赖报告ldd.(我相信在这个实例中动态加载Python库.)
[ 后来添加:这与Boost.Python无关.此外,如果使用低级Python C API,则可以编译Python模块,而不是与libpython链接,它将起作用.但是,请参阅下面的评论和答案,说明应该链接到libpython.]
那么,我怎么能系统地发现不必要的链接而不是使用反复试验呢?什么是一个很好的通用程序,不仅仅是这个例子?
[ 后来补充:这是我从评论中学到的问题.当我发布这个问题时,下面的事实对我来说并不清楚,所以我现在将它们拼出来,以便将来访问此讨论的人受益,即使这些事情对于有用的评论者来说是显而易见的.(谢谢!)
解析符号在Linux中以传递方式工作(如用户MvG和millimoose所指出的).假设程序A需要解析来自libB和libC的符号.进一步假设一个是对链接libB和libB是对链接的libC.然后一个可以装载即使它没有直接提及执行的libC.
然而,正如评论者指出的那样,依靠这种传递性是不好的做法.对于用C/C++编写的Python模块,这意味着应该链接libpython.对于一般情况下,我们的目标应该不会是确定的链接和执行,为我的一部开拓创新的问题在某种程度上暗示,但真正提供链接必要的库中,以便需要的库的最小列表的所有符号可以解决直接.
总结Salgar的答案,这些信息通常只能从所用库的文档中获得.此外,GCC链接器标志-Wl,--as-needed对于识别真正不必要的库非常有用.
std::memory_order当涉及到三个线程时,这是关于C++ 11中的规则的问题.比如说,一个线程生产者保存一个值并设置一个标志.然后,另一个线程中继在设置另一个标志之前等待该标志.最后,第三个线程消费者等待来自中继的标志,该标志应该表示data已为消费者准备好.
这是一个最小程序,采用C++参考中的示例风格(http://en.cppreference.com/w/cpp/atomic/memory_order):
#include <thread>
#include <atomic>
#include <cassert>
std::atomic<bool> flag1 = ATOMIC_VAR_INIT(false);
std::atomic<bool> flag2 = ATOMIC_VAR_INIT(false);
int data;
void producer()
{
data = 42;
flag1.store(true, std::memory_order_release);
}
void relay_1()
{
while (!flag1.load(std::memory_order_acquire))
;
flag2.store(true, std::memory_order_release);
}
void relay_2()
{
while (!flag1.load(std::memory_order_seq_cst))
;
flag2.store(true, std::memory_order_seq_cst);
}
void relay_3()
{
while (!flag1.load(std::memory_order_acquire))
;
// Does the following line make a difference?
data = data;
flag2.store(true, std::memory_order_release); …Run Code Online (Sandbox Code Playgroud) 指针上的operator []的自然参数类型是什么,如:
struct foo
{
value_t operator[](<TYPE?> i)
{ return data[i]; }
value_t * data;
};
Run Code Online (Sandbox Code Playgroud)
我知道我可以提供任何整数类型,但是数组索引的自然类型是什么,即.哪一个不会导致隐式转换?