Python と C 言語の混合プログラミングの例

WBOY
リリース: 2016-06-16 08:43:56
オリジナル
1341 人が閲覧しました

最近、ネットワーク速度をテストするために、一部のビジネス サーバーでは icmp をオフにする必要があります。この場合、通常の ping ではニーズを満たすことができないため、実行効率が高いため、tcp ポートに基づいて ping プログラムを作成しました。 Pythonは開発効率は高いですが、実行効率はCに劣ります。大規模に利用する必要があるため、コードのコア部分の実装にはCが使用されます。 、この部分は Python モジュールとして実装されており、C モジュールは Python によって呼び出されます。以下のコードを投稿してください

コードをコピー コードは次のとおりです:

/* tcpportping.c */
#include
#include
#include
#include
#include
#include
#include

/* count time functions */
static double mytime(void)
{
    struct timeval tv;
    if (gettimeofday(&tv, NULL) == -1)
        return 0.0;

    return (double)tv.tv_usec + (double)tv.tv_sec * 1000000;
}

static PyObject *                                 /* returns object */
tcpping(PyObject *self, PyObject *args )
{
    struct  sockaddr_in addr;
    struct  hostent *hp;
    double  time;
    char    *host = NULL;
    int     fd;
    int     port, timeout;

    if (!PyArg_ParseTuple(args, "sii", &host, &port, &timeout))  /* convert Python -> C */
        return NULL;                              /* null=raise exception */

    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return Py_BuildValue("d", -1.0); /* convert C -> Python */
    }

    bzero((char *)&addr, sizeof(addr));
    if ((hp = gethostbyname(host)) == NULL) {
        return Py_BuildValue("d", -2.0);        /* convert C -> Python */
    }
    bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);

    struct timeval tv;

    tv.tv_sec = 0;
    tv.tv_usec = timeout * 1000;

    double stime = mytime();
    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
return Py_BuildValue("d", -3.0); /* convert C -> Python */
    }
    fd_set read, write;
    FD_ZERO(&read);
    FD_ZERO(&write);

    FD_SET(fd, &read);
    FD_SET(fd, &write);

    if (select(fd + 1, &read, &write, NULL, &tv) == 0) {
        close(fd);
        return Py_BuildValue("d", -4.0);        /* convert C -> Python */
    }

    double etime = mytime();
    time = etime - stime;
    if (!FD_ISSET(fd, &read) && !FD_ISSET(fd, &write)) {
        close(fd);
        return Py_BuildValue("d", -4.0);        /* convert C -> Python */
    }
    close(fd);
    return Py_BuildValue("d", time/1000);        /* convert C -> Python */
}

/* registration table  */
static struct PyMethodDef portping_methods[] = {
    {"tcpping", tcpping, METH_VARARGS},       /* method name, C func ptr, always-tuple */
    {NULL, NULL}                   /* end of table marker */
};

/* module initializer */
void inittcpportping( )                       /* called on first import */
{                                      /* name matters if loaded dynamically */
    (void) Py_InitModule("tcpportping", portping_methods);   /* mod name, table ptr */
}

Python モジュールにコンパイルします

コードをコピーします コードは次のとおりです:
gcc tcpportping.c -I/usr/include /python2.4 -shared -L/usr/bin -fpic -lpython2.4 -o tcpportping.so

次は、Python が C モジュールを呼び出すためのコードです:

コードをコピーします コードは次のとおりです:
# !/usr/bin/env python

import tcpportping
インポート時間

i = 0
while i < 5:
t = tcpportping.tcpping('www .baidu.com', 80, 1000)
if t print "time out"
else:
print t
time.sleep(0.5)
i += 1
ポート ping の結果を得るために Python コードを実行します。テスト状況から、このプログラムの実行結果は通常の ping の結果とほぼ同じです。
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート