小编Dan*_*iel的帖子

'const'方法可以改变什么?

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,但确实会更改数组的内容.

c++

24
推荐指数
3
解决办法
7311
查看次数

生成器在Python 2和3中统一迭代字典

有没有办法有效地迭代在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)

然而,词典的方法不容易被重新定义一样mapzip.)

有任何想法吗?

python python-3.x

8
推荐指数
2
解决办法
2929
查看次数

全局解释器锁定和访问数据(例如,对于NumPy阵列)

我正在为Python编写一个C扩展,它应该在对数据进行操作时释放全局解释器锁.我认为我已经很好地理解了GIL的机制,但仍然存在一个问题:当线程不拥有GIL时,我可以访问Python对象中的数据吗?例如,我想从C函数中的(大)NumPy数组中读取数据,而我仍然希望允许其他线程在其他CPU内核上执行其他操作.C函数应该

  • 发布GIL Py_BEGIN_ALLOW_THREADS
  • 无需使用Python函数即可读取和处理数据
  • 甚至将数据写入先前构造的NumPy数组
  • 重新获取GIL Py_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_THREADSPy_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)

python numpy python-c-api

7
推荐指数
2
解决办法
2248
查看次数

我如何知道要链接哪些库?

有没有办法(在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需要解析来自libBlibC的符号.进一步假设一个是对链接libBlibB是对链接的libC.然后一个可以装载即使它没有直接提及执行的libC.

然而,正如评论者指出的那样,依靠这种传递性是不好的做法.对于用C/C++编写的Python模块,这意味着应该链接libpython.对于一般情况下,我们的目标应该不会是确定的链接和执行,为我的一部开拓创新的问题在某种程度上暗示,但真正提供链接必要的库中,以便需要的库的最小列表的所有符号可以解决直接.

总结Salgar的答案,这些信息通常只能从所用库的文档中获得.此外,GCC链接器标志-Wl,--as-needed对于识别真正不必要的库非常有用.

c c++

7
推荐指数
1
解决办法
1705
查看次数

同步谜语std :: memory_order和三个线程

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)

c++ atomic c++11

5
推荐指数
1
解决办法
417
查看次数

指针和数组上的operator []的索引参数类型

指针上的operator []的自然参数类型是什么,如:

struct foo
{
  value_t operator[](<TYPE?> i)
    { return data[i]; }

  value_t * data;
};
Run Code Online (Sandbox Code Playgroud)

我知道我可以提供任何整数类型,但是数组索引的自然类型是什么,即.哪一个不会导致隐式转换?

c++

4
推荐指数
1
解决办法
184
查看次数

标签 统计

c++ ×4

python ×2

atomic ×1

c ×1

c++11 ×1

numpy ×1

python-3.x ×1

python-c-api ×1