python 과 C 언어 를 혼합 하여 만 드 는 몇 가지 방식(추천)
Python 은 GIL 문제 로 인해 다 중 스 레 드 가 다 중 핵 을 충분히 이용 하지 못 했 지만 나중에 multiprocess 는 다 중 프로 세 스 의 측면 에서 다 중 핵 을 이용 할 수 있 고 심지어 affinity 는 구체 적 인 CPU 핵 을 연결 할 수 있 으 며 이 문제 도 해결 한 셈 이다.기본적으로 스 택 언어 이지 만 효율 성 을 위해 C 언어 와 의 혼합 을 고려 할 때 도 있다.혼합 편성 은 컴퓨터 에서 피 할 수 없 는 화제 로 관련 된 것 이 매우 많다.기술,구조,단체 상황,관리,고객 등 각 부분 이 모두 이에 영향 을 미 칠 수 있다.혼합 편성 이라는 문 제 는 내 가 생각 할 때 다시 전문 적 인 토론 을 하고 싶다.본 고 는 python 과 C 를 혼합 하 는 방식 만 말 하고 대체적으로 다음 과 같은 몇 가지 방식 이 있다(본 고의 배경 은 linux 이 고 다른 플랫폼 은 비교 할 수 있다).
공유 라 이브 러 리
C 언어 컴 파일 을 사용 하여 공유 라 이브 러 리 를 만 든 다음 python 은 ctype 라 이브 러 리 의 cdll 을 사용 하여 공유 라 이브 러 리 를 엽 니 다.
예 를 들 어 다음 과 같다.C 언어 코드 는?
/* func.c */int func(int a)
{
return a*a;
}
python 코드
#!/usr/bin/env python
#test_so.pyfrom ctypes import cdll
import os
p = os.getcwd() + '/libfunc.so'
f = cdll.LoadLibrary(p)
print f.func(99)
테스트 는 다음 과 같다.
$ gcc -fPIC -shared func.c -o libfunc.so
$ ./test_so.py
9801
subprocessC 언어 는 실행 가능 한 완전한 파일 을 설계 한 다음 에 python 은 subprocess 를 통 해 실행 가능 한 파일 을 실행 합 니 다.본질 적 으로 fork+execve 입 니 다.
예 를 들 어 다음 과 같다.C 언어 코드 는?
/* test.c */
#include <stdio.h>
int func(int a)
{
return a*a;
}
int main(int argc, char **argv)
{
int x;
sscanf(argv[1], "%d", &x);
printf("%d
", func(x));
return 0;
}
Python 코드#!/usr/bin/env python
# test_subprocess.py
import os
import subprocess
subprocess.call([os.getcwd()+'/a.out', '99'])
테스트 는 다음 과 같다.
$ gcc test.c -o a.out
$ ./test_subprocess.py
9801
C 언어 에서 python 프로그램 실행
C 언어 는 popen/system 을 사용 하거나 시스템 호출 급 fork+exec 로 python 프로그램 을 직접 실행 하 는 것 도 혼합 편성 수단 이다.
예 를 들 어 다음 과 같 습 니 다.Python 코드 는 다음 과 같 습 니 다.
#!/usr/bin/env python
# test.py
import sys
x = int(sys.argv[1])
print x*x
C 언어 코드 는 다음 과 같 습 니 다.
/* test.c */
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
char s[1024];
int ret;
f = popen("./test.py 99", "r");
while((ret=fread(s,1,1024,f))>0) {
fwrite(s,1,ret,stdout);
}
fclose(f);
return 0;
}
테스트 는 다음 과 같다.
$ gcc test.c
$ ./a.out
9801
python 의 C 언어 확장 지원많은 프로 그래 밍 언어 가 C 언어 확장 에 지원 을 추 가 했 습 니 다.이것 은 두 가지 이유 가 있 습 니 다.(1)언어 디자인 초기 에 C 언어 가 있 는 라 이브 러 리 를 충분히 이용 하여 많은 확장 을 할 수 있 었 습 니 다.(2)C 언어의 운행 효율 이 높다.
python 도 예 외 는 아니다.태 어 난 날 부터 많은 라 이브 러 리 는 C 언어 로 쓰 여 있다.python 의 C 언어 확장 에는 python 의 데이터 구조 와 C 언어의 대응 이 포함 되 어 있 습 니 다.확장 방법 은 C 언어 로 공유 라 이브 러 리 를 만 드 는 것 입 니 다.다만 이 공유 라 이브 러 리 의 인 터 페 이 스 는 규범 적 이 고 python 에 의 해 식별 할 수 있 습 니 다.
확장 방법 을 설명 하기 위해 서 저 는 먼저 python 에서 의 함수 기능 을 가정 합 니 다.코드 는 다음 과 같 습 니 다.
def func(*a):
res=1
for i in range(len(a)):
res *= sum(a[i])
return res
위 와 같이 원 하 는 함수 기능 은 매개 변 수 는 여러 개의 숫자 로 구 성 된 목록(다른 데이터 구 조 를 제외 하고)으로 각 목록 의 요소 의 합 을 되 돌려 주 는 것 입 니 다.우선 python 코드 를 썼 습 니 다.아래 와 같 습 니 다.
#!/usr/bin/env python
# test.py
import colin
def func(*a):
res=1
for i in range(len(a)):
res *= sum(a[i])
return res
a = [1,2,3]
b = [4,5,6]
c = [7,8]
d = [9]
e = [10,11,12,13,14]
f = colin.func2(99)
g = colin.func3(a,b,c,d,e)
h = func3(a,b,c,d,e)
print "f = ",f
print "g = ",g
print "h = ",h
이전에 테스트 해 왔 던 제곱 func 를 가 져 옵 니 다.이것 은 상대 적 으로 간단 합 니 다.python 이 쓴 func 가 C 언어 로 확 장 된 결과 와 일치 하 기 를 바 랍 니 다.먼저 C 언어 로 이 함수 들 의 실현 을 적 었 습 니 다.그 중에서 func 3 는 임의의 긴 배열 을 나타 내 는 데이터 구조 y 를 사 용 했 습 니 다.t,그리고 xt 는 하나의 배열 을 나타 내 는 데 쓰 인 다.
/* colin.h */
#ifndef Colin_h
#define Colin_h
typedef struct {
int *a;
int len;
} x_t;
typedef struct {
x_t *ax;
int len;
} y_t;
int func2(int a);
int func3(y_t *p);
void free_y_t(y_t *p);
#endif
/* colin.c */
#include "colin.h"
#include <stdlib.h>
int func2(int a)
{
return a*a;
}
int func3(y_t *p)
{
int result;
int sum;
int i, j;
result = 1;
for(i=0;i<p->len;i++) {
sum = 0;
for(j=0;j<p->ax[i].len;j++)
sum += p->ax[i].a[j];
result *= sum;
}
return result;
}
void free_y_t(y_t *p)
{
int i;
for(i=0;i<p->len;i++) {
free(p->ax[i].a);
}
free(p->ax);
}
위 에서 세 개의 함 수 를 정 의 했 는데 func 2 는 제곱 을 대표 하고 func 3 는 앞에서 말 한 기능 을 대표 하 며 또 yt.이 구 조 는 모두 동적 으로 분 배 될 수 있 기 때문에 메모리 반환 방법 을 줍 니 다.방금 python 확장 이 라 고 했 으 니 이 공유 라 이브 러 리 의 인 터 페 이 스 를 표준화 해 야 합 니 다.그래서 우 리 는 포장 을 해서 python 에 불 러 오 는 입 구 를 주 었 다.
/* wrap.c */
#include <Python.h>
#include <stdlib.h>
#include "colin.h"
PyObject* wrap_func2(PyObject* self, PyObject* args)
{
int n, result;
/* , "i" */
if (!PyArg_ParseTuple(args, "i", &n))
return NULL;
/* C */
result = func2(n);
/* python */
return Py_BuildValue("i", result);
}
PyObject* wrap_func3(PyObject* self, PyObject* args)
{
int n, result;
int i, j;
int size, size2;
PyObject *p,*q;
y_t *y;
y = malloc(sizeof(y_t));
/* , */
size = PyTuple_Size(args);
/* */
y->len = size;
y->ax = malloc(sizeof(x_t)*size);
/* python ( ) */
for(i=0;i<size;i++) {
/* i , */
p = PyTuple_GetItem(args, i);
/* */
size2 = PyList_Size(p);
/* */
y->ax[i].len = size2;
y->ax[i].a = malloc(sizeof(int)*size2);
/* , */
for(j=0;j<size2;j++) {
q = PyList_GetItem(p, j);
PyArg_Parse(q,"i",&y->ax[i].a[j]);
}
}
/* C */
result = func3(y);
free_y_t(y);
free(y);
/* python */
return Py_BuildValue("i", result);
}
/* , , ( ) , */
static PyMethodDef colinMethods[] =
{
{"func2", wrap_func2, METH_VARARGS, "Just a test"},
{"func3", wrap_func3, METH_VARARGS, "Just a test"},
{NULL, NULL, METH_NOARGS, NULL}
};
/* python */
/* , colin, initcolin */
void initcolin()
{
PyObject *m;
m = Py_InitModule("colin", colinMethods);
}
그 과정 에서 PyArgVaParse 는 기능 이 더욱 강해 야 하 는데 반복 적 으로 테스트 가 성공 하지 못 했 고 문 서 를 자세히 보지 못 했다.테스트 해 봐.
$ gcc -I /usr/include/python2.7/ -fPIC -shared colin.c wrap.c -o colin.so
$ ./test.py
f = 9801
g = 729000
h = 729000
C 언어 가 쓴 함수 와 python 이 쓴 함수 결과 가 일치 하 는 것 을 볼 수 있 습 니 다.이상 의 이 평론 python 과 C 언어 를 혼합 한 몇 가지 방식(추천)은 바로 편집장 이 여러분 에 게 공유 한 모든 내용 입 니 다.여러분 에 게 참고 가 될 수 있 고 많은 응원 을 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.