本节记录一下多线程、多进程中调用 Python 解析器。
目录
- 如何在 C++ 中调用 python 解析器来执行 python 代码(一)?
- 如何在 C++ 中调用 python 解析器来执行 python 代码(二)?
- 如何在 C++ 中调用 python 解析器来执行 python 代码(三)?
- 如何在 C++ 中调用 python 解析器来执行 python 代码(四)?
多线程模式
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;
int
run_py()
{
wchar_t *program = Py_DecodeLocale("./a.out", NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
const char *script = ""
"from time import time,sleep,ctime\n"
"sleep(3)\n"
"print('Today is', ctime(time()))\n";
PyRun_SimpleString(script);
if (Py_FinalizeEx() < 0) {
exit(120);
}
PyMem_RawFree(program);
return 0;
}
void threadFun1(int n) {
cout << "---thread " << n << " running\n";
run_py();
cout << "n=" << n << endl;
}
int
main(int argc, char *argv[])
{
thread thread1 = std::thread(threadFun1, 1);
thread thread2 = std::thread(threadFun1, 2);
thread thread3 = std::thread(threadFun1, 3);
thread thread4 = std::thread(threadFun1, 4);
thread1.join();
thread2.join();
thread3.join();
thread4.join();
cout << "main finished" << endl;
return 0;
}
这种方式运行,会直接 coredump!
$make
g++ -std=c++11 -I/usr/include/python3.6m -I/usr/include/python3.6m -Wno-unused-result -Wsign-compare -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -L/usr/lib64 -lpython3.6m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic main.cpp
./[xiaochu.yh ~/tools/c-python] $./a.out
main finished
Segmentation fault (core dumped)
多进程模式
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;
int
run_py()
{
wchar_t *program = Py_DecodeLocale("./a.out", NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
const char *script = ""
"from time import time,sleep,ctime\n"
"sleep(3)\n"
"print('Today is', ctime(time()))\n";
PyRun_SimpleString(script);
if (Py_FinalizeEx() < 0) {
exit(120);
}
PyMem_RawFree(program);
return 0;
}
void threadFun1(int n) {
cout << "---thread " << n << " running\n";
run_py();
cout << "n=" << n << endl;
}
int
main(int argc, char *argv[])
{
if (fork() == 0) {
thread thread1 = std::thread(threadFun1, 1);
thread1.join();
} else if (fork() == 0) {
thread thread2 = std::thread(threadFun1, 2);
thread2.join();
} else if (fork() == 0) {
thread thread3 = std::thread(threadFun1, 3);
thread3.join();
} else if (fork() == 0) {
thread thread4 = std::thread(threadFun1, 4);
thread4.join();
} else {
cout << "main finished" << endl;
}
return 0;
}
这种模式可以正常执行:
$make
g++ -std=c++11 -I/usr/include/python3.6m -I/usr/include/python3.6m -Wno-unused-result -Wsign-compare -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -L/usr/lib64 -lpython3.6m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic main.cpp
$./a.out
main finished
Today is Thu Mar 2 11:27:01 2023
---thread 1 running
Today is Thu Mar 2 11:27:01 2023
n=1
Today is Thu Mar 2 11:27:01 2023
---thread 2 running
Today is Thu Mar 2 11:27:01 2023
n=2
---thread 4 running
n=4
---thread 3 running
n=3