diff --git "a/Python_Advance/\351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/\351\235\231\346\200\201\346\226\271\346\263\225,\347\261\273\346\226\271\346\263\225\345\222\214\345\256\236\344\276\213\346\226\271\346\263\225.ipynb" "b/Python_Advance/\351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/\351\235\231\346\200\201\346\226\271\346\263\225,\347\261\273\346\226\271\346\263\225\345\222\214\345\256\236\344\276\213\346\226\271\346\263\225.ipynb" index 4e87d18..b6859c0 100755 --- "a/Python_Advance/\351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/\351\235\231\346\200\201\346\226\271\346\263\225,\347\261\273\346\226\271\346\263\225\345\222\214\345\256\236\344\276\213\346\226\271\346\263\225.ipynb" +++ "b/Python_Advance/\351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/\351\235\231\346\200\201\346\226\271\346\263\225,\347\261\273\346\226\271\346\263\225\345\222\214\345\256\236\344\276\213\346\226\271\346\263\225.ipynb" @@ -575,7 +575,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.0" + "version": "3.5.1" } }, "nbformat": 4, diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/.DS_Store" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/.DS_Store" new file mode 100644 index 0000000..750ca99 Binary files /dev/null and "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/.DS_Store" differ diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/.ipynb_checkpoints/\347\224\250ctypes\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245\345\272\223\344\272\244\344\272\222-checkpoint.ipynb" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/.ipynb_checkpoints/\347\224\250ctypes\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245\345\272\223\344\272\244\344\272\222-checkpoint.ipynb" new file mode 100644 index 0000000..11af4d0 --- /dev/null +++ "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/.ipynb_checkpoints/\347\224\250ctypes\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245\345\272\223\344\272\244\344\272\222-checkpoint.ipynb" @@ -0,0 +1,643 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 用types与动态链接库交互" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[ctypes](https://docs.python.org/2/library/ctypes.html)是原版python和pypy都支持的一种与动态链接库(就是.so或者.dll那个文件)交互的方式,因此它也是最方便的一种与c语言混合编程的方式.c还是那个c,python还是那个python,不用再学其他的了,这也是简单情况下最推荐的一种与c直接交互的方式.\n", + "\n", + "ctypes 有以下优点:\n", + "\n", + "+ Python内建,不需要单独安装\n", + "+ 可以直接调用二进制的动态链接库 \n", + "+ 对基本类型的相互映射有良好的支持\n", + "\n", + "ctypes 有以下缺点:\n", + "\n", + "+ 平台兼容性差\n", + "+ 不能够直接调用动态链接库中未经导出的函数或变量\n", + "+ 对C++的支持差\n", + "\n", + "\n", + "**事先申明:**本文写在mac osx平台,使用的编译工具是clang,其他平台都没试过,有兴趣的小朋友可以自己摸索下" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> 例子:一个二维向量运算" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### c代码:\n", + "\n", + "v.c\n", + "\n", + "```c\n", + "#include \n", + "#include \n", + "#include \n", + "\n", + "//向量结构体\n", + "typedef struct{\n", + " float x,y;\n", + " char repr[50];\n", + "}Vector;\n", + "\n", + "Vector add(Vector a,Vector b){\n", + " Vector c;\n", + " c.x = a.x+b.x;\n", + " c.y = a.y+b.y;\n", + " char tempx[10];\n", + " char tempy[10];\n", + " //char x = itoa(c.x,&tempx,10);\n", + " //char y = itoa(c.y,&tempy,10);\n", + " int len = sprintf(c.repr, \"\\n\",c.x,c.y);\n", + " //c.repr = \"\";\n", + " return c;\n", + "}\n", + "\n", + "int main(void){\n", + " Vector a,b,c;\n", + " a.x = 10.0;\n", + " a.y = 20.0;\n", + " strcpy(a.repr,\"\");\n", + "\n", + " b.x = 1.0;\n", + " b.y = 2.0;\n", + " strcpy(b.repr,\"\");\n", + " c = add(a,b);\n", + " printf(\"x %f y %f\\n\",c.x,c.y);\n", + " printf(\"%s\\n\",c.repr);\n", + " return 0;\n", + "}\n", + "```\n", + "\n", + "编译运行下:\n", + "\n", + "```bash\n", + "gcc v.c -o vtest\n", + "./vtest\n", + "```\n", + "\n", + "结果正常" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 修改成动态链接库(把那个显示结果的省了)\n", + "\n", + "vector.h\n", + "\n", + "```c\n", + "#ifndef VECTOR_HEAD_\n", + "#define VECTOR_HEAD_\n", + "\n", + "//向量结构体\n", + "typedef struct{\n", + " float x,y;\n", + "}Vector;\n", + "\n", + "//向量加法\n", + "Vector add(Vector a,Vector b);\n", + "\n", + "#endif\n", + "```\n", + "\n", + "vector.c\n", + "\n", + "```c\n", + "#include \n", + "#include \n", + "#include \n", + "\n", + "#include \"vector.h\"\n", + "\n", + "//向量结构体\n", + "Vector add(Vector a,Vector b){\n", + " Vector c;\n", + " c.x = a.x+b.x;\n", + " c.y = a.y+b.y;\n", + " return c;\n", + "}\n", + "```\n", + "编译成动态链接库\n", + "\n", + "```bash\n", + "gcc -shared -fPIC -o libvec.so vector.c\n", + "```\n", + "\n", + "这样就生成一个v.so文件,我们先来用c语言试试看调用\n", + "\n", + "vectorTest.c\n", + "\n", + "```c\n", + "#include \n", + "#include \n", + "\n", + "#include \"vector.h\"\n", + "\n", + "int main(void){\n", + " Vector a,b,c;\n", + " a.x = 10.0;\n", + " a.y = 20.0;\n", + "\n", + " b.x = 1.0;\n", + " b.y = 2.0;\n", + " c = add(a,b);\n", + " printf(\"x %f y %f\\n\",c.x,c.y);\n", + " return 0;\n", + "}\n", + "```\n", + "\n", + "编译:\n", + "\n", + "```bash\n", + "gcc vectorTest.c -o vectorTest -L ./ -lvec\n", + "./vectorTest\n", + "```\n", + "\n", + "结果正常" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 用ctypes调用这个动态链接库\n", + "\n", + "到正题了,我们用这个ctypes调用下动态库试试" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from ctypes import CDLL,c_float,c_char_p,Structure,POINTER,c_int,pointer" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Vector(Structure):\n", + " _fields_ = [(\"x\",c_float),(\"y\",c_float)]\n", + " def __str__(self):\n", + " return \"Vector:<{this.x},{this.y}>\".format(this=self)\n", + " def __repr__(self):\n", + " return self.__str__()\n", + " def __add__(self,that):\n", + " dll = CDLL(\"libvec.so\")\n", + " dll.add.argtypes = (Vector,Vector)\n", + " dll.add.restype = Vector\n", + " return dll.add(self,that)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "v1 = Vector(1,2)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Vector:<1.0,2.0>" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v1" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "v2 = Vector(10,20)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Vector:<10.0,20.0>" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v2" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [], + "source": [ + "v3 = v1+v2" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Vector:<11.0,22.0>" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "可喜可贺~~" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ctypes内置数据类型映射:\n", + "\n", + "\n", + "ctypes type|c type|Python type\n", + "---|---|---\n", + "c_char|char\t|1-character string\n", + "c_wchar\t|wchar_t\t|1-character unicode string\n", + "c_byte\t|char\t|int/long\n", + "c_ubyte\t|unsigned char\t|int/long\n", + "c_short\t|short\t|int/long\n", + "c_ushort\t|unsigned short\t|int/long\n", + "c_int\t|int\t|int/long\n", + "c_uint\t|unsigned int\t|int/long\n", + "c_long\t|long\t|int/long\n", + "c_ulong\t|unsigned long\t|int/long\n", + "c_longlong\t|__int64 or long long\t|int/long\n", + "c_ulonglong\t|unsigned __int64 or unsigned long long\t|int/long\n", + "c_float\t|float\t|float\n", + "c_double\t|double\t|float\n", + "c_char_p\t|char * (NUL terminated)\t|string or None\n", + "c_wchar_p\t|wchar_t * (NUL terminated)\t|unicode or None\n", + "c_void_p\t|void *|int/long or None" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "需要注意的是:\n", + "+ 关于指定映射类型,如果指定c中的返回值类型,则是`dll.FUNCNAME.restype = TYPE`,如果函数的返回值是`void`那么你可以赋值为 `None`,如果不设定,则默认是`int`类型;\n", + "+ 如果是传入参数类型指定,则使用`dll.FUNCNAME.argtypes = (TYPE1, TYPE2...)`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ctypes 和 指针" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "如何创建一个 ctypes 的指针呢?这里有三个跟指针有个的 ctypes 里的函数,\n", + "\n", + "函数\t|说明\n", + "---|---\n", + "byref(x [, offset])\t|返回 x 的地址,x 必须为 ctypes 类型的一个实例。相当于 c 的 &x 。 offset 表示偏移量。\n", + "pointer(x)\t|创建并返回一个指向 x 的指针实例, x 是一个实例对象。\n", + "POINTER(type)\t|返回一个类型,这个类型是指向 type 类型的指针类型, type 是 ctypes 的一个类型。\n", + "\n", + "\n", + "\n", + "byref 很好理解,传递参数的时候就用这个,用 pointer 创建一个指针变量也行,不过 byref 更快。\n", + "\n", + "而 pointer 和 POINTER 的区别是,pointer 返回一个实例,POINTER 返回一个类型。甚至你可以用 POINTER 来做 pointer 的工作:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "a = c_int(6) # 创建一个 c_int 实例" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "c_int(6)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "b = pointer(a) # 创建指针" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.LP_c_int at 0x103d618c0>" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "c = POINTER(c_int)(a) # 创建指针" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.LP_c_int at 0x103d70050>" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "c_int(6)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b.contents #输出 a 的值" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "c_int(6)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c.contents # 输出 a 的值" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.LP_Vector at 0x103d704d0>" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pointer(v3)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.LP_Vector at 0x103d70560>" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "POINTER(Vector)(v3)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Vector:<11.0,22.0>" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "POINTER(Vector)(v3).contents" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "11.0" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "POINTER(Vector)(v3).contents.x" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/libvec.so" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/libvec.so" new file mode 100755 index 0000000..32a0209 Binary files /dev/null and "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/libvec.so" differ diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/v.c" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/v.c" new file mode 100644 index 0000000..22c8824 --- /dev/null +++ "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/v.c" @@ -0,0 +1,37 @@ +#include +#include +#include + +//向量结构体 +typedef struct{ + float x,y; + char repr[50]; +}Vector; + +Vector add(Vector a,Vector b){ + Vector c; + c.x = a.x+b.x; + c.y = a.y+b.y; + char tempx[10]; + char tempy[10]; + //char x = itoa(c.x,&tempx,10); + //char y = itoa(c.y,&tempy,10); + int len = sprintf(c.repr, "\n",c.x,c.y); + //c.repr = ""; + return c; +} + +int main(void){ + Vector a,b,c; + a.x = 10.0; + a.y = 20.0; + strcpy(a.repr,""); + + b.x = 1.0; + b.y = 2.0; + strcpy(b.repr,""); + c = add(a,b); + printf("x %f y %f\n",c.x,c.y); + printf("%s\n",c.repr); + return 0; +} diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/v.so" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/v.so" new file mode 100755 index 0000000..18cd843 Binary files /dev/null and "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/v.so" differ diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.c" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.c" new file mode 100644 index 0000000..bb5c14e --- /dev/null +++ "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.c" @@ -0,0 +1,13 @@ +#include +#include +#include + +#include "vector.h" + +//向量结构体 +Vector add(Vector a,Vector b){ + Vector c; + c.x = a.x+b.x; + c.y = a.y+b.y; + return c; +} diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.h" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.h" new file mode 100644 index 0000000..f8185a6 --- /dev/null +++ "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.h" @@ -0,0 +1,12 @@ +#ifndef VECTOR_HEAD_ +#define VECTOR_HEAD_ + +//向量结构体 +typedef struct{ + float x,y; +}Vector; + +//向量加法 +Vector add(Vector a,Vector b); + +#endif diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.so" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.so" new file mode 100755 index 0000000..0494fd9 Binary files /dev/null and "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vector.so" differ diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vectorTest" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vectorTest" new file mode 100755 index 0000000..93e5574 Binary files /dev/null and "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vectorTest" differ diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vectorTest.c" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vectorTest.c" new file mode 100644 index 0000000..7136776 --- /dev/null +++ "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vectorTest.c" @@ -0,0 +1,16 @@ +#include +#include + +#include "vector.h" + +int main(void){ + Vector a,b,c; + a.x = 10.0; + a.y = 20.0; + + b.x = 1.0; + b.y = 2.0; + c = add(a,b); + printf("x %f y %f\n",c.x,c.y); + return 0; +} diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vtest" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vtest" new file mode 100755 index 0000000..c31a8fd Binary files /dev/null and "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/vtest" differ diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/\347\224\250ctypes\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245\345\272\223\344\272\244\344\272\222.ipynb" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/\347\224\250ctypes\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245\345\272\223\344\272\244\344\272\222.ipynb" new file mode 100644 index 0000000..11af4d0 --- /dev/null +++ "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/C\346\211\251\345\261\225/\347\224\250ctypes\345\222\214C\344\272\244\344\272\222/\347\224\250ctypes\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245\345\272\223\344\272\244\344\272\222.ipynb" @@ -0,0 +1,643 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 用types与动态链接库交互" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[ctypes](https://docs.python.org/2/library/ctypes.html)是原版python和pypy都支持的一种与动态链接库(就是.so或者.dll那个文件)交互的方式,因此它也是最方便的一种与c语言混合编程的方式.c还是那个c,python还是那个python,不用再学其他的了,这也是简单情况下最推荐的一种与c直接交互的方式.\n", + "\n", + "ctypes 有以下优点:\n", + "\n", + "+ Python内建,不需要单独安装\n", + "+ 可以直接调用二进制的动态链接库 \n", + "+ 对基本类型的相互映射有良好的支持\n", + "\n", + "ctypes 有以下缺点:\n", + "\n", + "+ 平台兼容性差\n", + "+ 不能够直接调用动态链接库中未经导出的函数或变量\n", + "+ 对C++的支持差\n", + "\n", + "\n", + "**事先申明:**本文写在mac osx平台,使用的编译工具是clang,其他平台都没试过,有兴趣的小朋友可以自己摸索下" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> 例子:一个二维向量运算" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### c代码:\n", + "\n", + "v.c\n", + "\n", + "```c\n", + "#include \n", + "#include \n", + "#include \n", + "\n", + "//向量结构体\n", + "typedef struct{\n", + " float x,y;\n", + " char repr[50];\n", + "}Vector;\n", + "\n", + "Vector add(Vector a,Vector b){\n", + " Vector c;\n", + " c.x = a.x+b.x;\n", + " c.y = a.y+b.y;\n", + " char tempx[10];\n", + " char tempy[10];\n", + " //char x = itoa(c.x,&tempx,10);\n", + " //char y = itoa(c.y,&tempy,10);\n", + " int len = sprintf(c.repr, \"\\n\",c.x,c.y);\n", + " //c.repr = \"\";\n", + " return c;\n", + "}\n", + "\n", + "int main(void){\n", + " Vector a,b,c;\n", + " a.x = 10.0;\n", + " a.y = 20.0;\n", + " strcpy(a.repr,\"\");\n", + "\n", + " b.x = 1.0;\n", + " b.y = 2.0;\n", + " strcpy(b.repr,\"\");\n", + " c = add(a,b);\n", + " printf(\"x %f y %f\\n\",c.x,c.y);\n", + " printf(\"%s\\n\",c.repr);\n", + " return 0;\n", + "}\n", + "```\n", + "\n", + "编译运行下:\n", + "\n", + "```bash\n", + "gcc v.c -o vtest\n", + "./vtest\n", + "```\n", + "\n", + "结果正常" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 修改成动态链接库(把那个显示结果的省了)\n", + "\n", + "vector.h\n", + "\n", + "```c\n", + "#ifndef VECTOR_HEAD_\n", + "#define VECTOR_HEAD_\n", + "\n", + "//向量结构体\n", + "typedef struct{\n", + " float x,y;\n", + "}Vector;\n", + "\n", + "//向量加法\n", + "Vector add(Vector a,Vector b);\n", + "\n", + "#endif\n", + "```\n", + "\n", + "vector.c\n", + "\n", + "```c\n", + "#include \n", + "#include \n", + "#include \n", + "\n", + "#include \"vector.h\"\n", + "\n", + "//向量结构体\n", + "Vector add(Vector a,Vector b){\n", + " Vector c;\n", + " c.x = a.x+b.x;\n", + " c.y = a.y+b.y;\n", + " return c;\n", + "}\n", + "```\n", + "编译成动态链接库\n", + "\n", + "```bash\n", + "gcc -shared -fPIC -o libvec.so vector.c\n", + "```\n", + "\n", + "这样就生成一个v.so文件,我们先来用c语言试试看调用\n", + "\n", + "vectorTest.c\n", + "\n", + "```c\n", + "#include \n", + "#include \n", + "\n", + "#include \"vector.h\"\n", + "\n", + "int main(void){\n", + " Vector a,b,c;\n", + " a.x = 10.0;\n", + " a.y = 20.0;\n", + "\n", + " b.x = 1.0;\n", + " b.y = 2.0;\n", + " c = add(a,b);\n", + " printf(\"x %f y %f\\n\",c.x,c.y);\n", + " return 0;\n", + "}\n", + "```\n", + "\n", + "编译:\n", + "\n", + "```bash\n", + "gcc vectorTest.c -o vectorTest -L ./ -lvec\n", + "./vectorTest\n", + "```\n", + "\n", + "结果正常" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 用ctypes调用这个动态链接库\n", + "\n", + "到正题了,我们用这个ctypes调用下动态库试试" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from ctypes import CDLL,c_float,c_char_p,Structure,POINTER,c_int,pointer" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Vector(Structure):\n", + " _fields_ = [(\"x\",c_float),(\"y\",c_float)]\n", + " def __str__(self):\n", + " return \"Vector:<{this.x},{this.y}>\".format(this=self)\n", + " def __repr__(self):\n", + " return self.__str__()\n", + " def __add__(self,that):\n", + " dll = CDLL(\"libvec.so\")\n", + " dll.add.argtypes = (Vector,Vector)\n", + " dll.add.restype = Vector\n", + " return dll.add(self,that)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "v1 = Vector(1,2)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Vector:<1.0,2.0>" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v1" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "v2 = Vector(10,20)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Vector:<10.0,20.0>" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v2" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [], + "source": [ + "v3 = v1+v2" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Vector:<11.0,22.0>" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "可喜可贺~~" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ctypes内置数据类型映射:\n", + "\n", + "\n", + "ctypes type|c type|Python type\n", + "---|---|---\n", + "c_char|char\t|1-character string\n", + "c_wchar\t|wchar_t\t|1-character unicode string\n", + "c_byte\t|char\t|int/long\n", + "c_ubyte\t|unsigned char\t|int/long\n", + "c_short\t|short\t|int/long\n", + "c_ushort\t|unsigned short\t|int/long\n", + "c_int\t|int\t|int/long\n", + "c_uint\t|unsigned int\t|int/long\n", + "c_long\t|long\t|int/long\n", + "c_ulong\t|unsigned long\t|int/long\n", + "c_longlong\t|__int64 or long long\t|int/long\n", + "c_ulonglong\t|unsigned __int64 or unsigned long long\t|int/long\n", + "c_float\t|float\t|float\n", + "c_double\t|double\t|float\n", + "c_char_p\t|char * (NUL terminated)\t|string or None\n", + "c_wchar_p\t|wchar_t * (NUL terminated)\t|unicode or None\n", + "c_void_p\t|void *|int/long or None" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "需要注意的是:\n", + "+ 关于指定映射类型,如果指定c中的返回值类型,则是`dll.FUNCNAME.restype = TYPE`,如果函数的返回值是`void`那么你可以赋值为 `None`,如果不设定,则默认是`int`类型;\n", + "+ 如果是传入参数类型指定,则使用`dll.FUNCNAME.argtypes = (TYPE1, TYPE2...)`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ctypes 和 指针" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "如何创建一个 ctypes 的指针呢?这里有三个跟指针有个的 ctypes 里的函数,\n", + "\n", + "函数\t|说明\n", + "---|---\n", + "byref(x [, offset])\t|返回 x 的地址,x 必须为 ctypes 类型的一个实例。相当于 c 的 &x 。 offset 表示偏移量。\n", + "pointer(x)\t|创建并返回一个指向 x 的指针实例, x 是一个实例对象。\n", + "POINTER(type)\t|返回一个类型,这个类型是指向 type 类型的指针类型, type 是 ctypes 的一个类型。\n", + "\n", + "\n", + "\n", + "byref 很好理解,传递参数的时候就用这个,用 pointer 创建一个指针变量也行,不过 byref 更快。\n", + "\n", + "而 pointer 和 POINTER 的区别是,pointer 返回一个实例,POINTER 返回一个类型。甚至你可以用 POINTER 来做 pointer 的工作:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "a = c_int(6) # 创建一个 c_int 实例" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "c_int(6)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "b = pointer(a) # 创建指针" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.LP_c_int at 0x103d618c0>" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "c = POINTER(c_int)(a) # 创建指针" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.LP_c_int at 0x103d70050>" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "c_int(6)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b.contents #输出 a 的值" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "c_int(6)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c.contents # 输出 a 的值" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.LP_Vector at 0x103d704d0>" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pointer(v3)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.LP_Vector at 0x103d70560>" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "POINTER(Vector)(v3)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Vector:<11.0,22.0>" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "POINTER(Vector)(v3).contents" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "11.0" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "POINTER(Vector)(v3).contents.x" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/mpi\346\211\251\345\261\225(mpi4py)/mpi4py.ipynb" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/mpi\346\211\251\345\261\225(mpi4py)/mpi4py.ipynb" deleted file mode 100755 index ba4a384..0000000 --- "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/mpi\346\211\251\345\261\225(mpi4py)/mpi4py.ipynb" +++ /dev/null @@ -1,60 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "mpi是c,c++,以及fortran下的并行框架,而[mpi4py](http://mpi4py.readthedocs.org/en/stable/)是它的python接口,pypy也可以使用呦\n", - "\n", - "安装它先要安装openmpi,然后安装numpy和cython" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> 例 " - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Overwriting hl.py\n" - ] - } - ], - "source": [ - "%%writefile hl.py\n", - "from mpi4py import MPI\n", - "comm = MPI.COMM_WORLD\n", - "rank = comm.Get_rank()\n", - "print(\"hello world\")\n", - "print(\"my rank is:\",rank)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " mpirun –np 3 python h1.py" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Pypy", - "language": "python", - "name": "pypy" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/mpi\346\211\251\345\261\225(mpi4py)/.ipynb_checkpoints/mpi4py-checkpoint.ipynb" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/\345\244\232\350\277\233\347\250\213\345\267\245\345\205\267/mpi\346\211\251\345\261\225(mpi4py)/.ipynb_checkpoints/mpi4py-checkpoint.ipynb" similarity index 100% rename from "Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/mpi\346\211\251\345\261\225(mpi4py)/.ipynb_checkpoints/mpi4py-checkpoint.ipynb" rename to "Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/\345\244\232\350\277\233\347\250\213\345\267\245\345\205\267/mpi\346\211\251\345\261\225(mpi4py)/.ipynb_checkpoints/mpi4py-checkpoint.ipynb" diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/mpi\346\211\251\345\261\225(mpi4py)/hl.py" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/\345\244\232\350\277\233\347\250\213\345\267\245\345\205\267/mpi\346\211\251\345\261\225(mpi4py)/hl.py" similarity index 100% rename from "Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/mpi\346\211\251\345\261\225(mpi4py)/hl.py" rename to "Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/\345\244\232\350\277\233\347\250\213\345\267\245\345\205\267/mpi\346\211\251\345\261\225(mpi4py)/hl.py" diff --git "a/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/\345\244\232\350\277\233\347\250\213\345\267\245\345\205\267/mpi\346\211\251\345\261\225(mpi4py)/mpi4py.ipynb" "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/\345\244\232\350\277\233\347\250\213\345\267\245\345\205\267/mpi\346\211\251\345\261\225(mpi4py)/mpi4py.ipynb" new file mode 100755 index 0000000..7d43351 --- /dev/null +++ "b/Python_Other_Topics/\346\211\251\345\261\225\344\270\216\346\200\247\350\203\275\344\274\230\345\214\226/\345\244\232\350\277\233\347\250\213\345\267\245\345\205\267/mpi\346\211\251\345\261\225(mpi4py)/mpi4py.ipynb" @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "mpi(Message Passing Interface的简称),也就是消息传递,是c,c++,以及fortran下的并行框架,而[mpi4py](http://mpi4py.readthedocs.org/en/stable/)是它的python接口,pypy也可以使用呦\n", + "\n", + "安装它先要安装openmpi,然后安装numpy和cython\n", + "\n", + "## MPI的工作方式:\n", + "\n", + "MPI就是启动一组MPI进程,每个进程都是执行同样的代码,然后每个进程都有一个ID,也就是rank来标记自己。假设一个CPU是你请的一个工人,共有10个工人。你有100块砖头要搬,然后很公平,让每个工人搬10块。这时候,你把任务写到一个任务卡里面,让10个工人都执行这个任务卡中的任务,也就是搬砖!这个任务卡中的“搬砖”就是你写的代码。然后10个CPU执行同一段代码。需要注意的是,代码里面的所有变量都是每个进程独有的,虽然名字相同。简单的理解就是工作室魔兽多开刷金..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> 例: helloworld" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "h1.py\n", + "\n", + "```python\n", + "from mpi4py import MPI\n", + "comm = MPI.COMM_WORLD\n", + "rank = comm.Get_rank()\n", + "print(\"hello world\")\n", + "print(\"my rank is:\",rank)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " mpirun –np 3 python h1.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Pypy", + "language": "python", + "name": "pypy" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git "a/Python_STD_LIB/\345\271\266\350\241\214\345\244\204\347\220\206/\345\244\232\347\272\277\347\250\213\346\250\241\345\235\227(threading).ipynb" "b/Python_STD_LIB/\345\271\266\350\241\214\345\244\204\347\220\206/\345\244\232\347\272\277\347\250\213\346\250\241\345\235\227(threading).ipynb" index 366ab81..67c5517 100755 --- "a/Python_STD_LIB/\345\271\266\350\241\214\345\244\204\347\220\206/\345\244\232\347\272\277\347\250\213\346\250\241\345\235\227(threading).ipynb" +++ "b/Python_STD_LIB/\345\271\266\350\241\214\345\244\204\347\220\206/\345\244\232\347\272\277\347\250\213\346\250\241\345\235\227(threading).ipynb" @@ -571,7 +571,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.12" } }, "nbformat": 4,