[Framework] Fix the issue that `CreatePaddlePredictor` method is not safe for multi-thread condition !4014
Created by: DannyIsFunny
【Issue】 Unknown segmentation error may occur when we use multi-thread to create many predictors at the same time. eg.
#include <iostream>
#include <vector>
#include "paddle_api.h" // NOLINT
#include <unistd.h>
#include <pthread.h>
using namespace paddle::lite_api; // NOLINT
#define NUM_THREADS 2
struct thread_data{
int thread_id;
char *message;
};
int64_t ShapeProduction(const shape_t& shape) {
int64_t res = 1;
for (auto i : shape) res *= i;
return res;
}
void* RunModel(void*arg) {
for(int i =0; i < 10; i++) {
// 1. Create CxxConfig
std::string model_dir = "mobilenet_v1";
CxxConfig config;
config.set_model_dir(model_dir);
config.set_valid_places({Place{TARGET(kX86), PRECISION(kFloat)},
Place{TARGET(kHost), PRECISION(kFloat)}});
// 2. Create PaddlePredictor by CxxConfig
std::shared_ptr<PaddlePredictor> predictor1 =
CreatePaddlePredictor<CxxConfig>(config);
std::cout << "Succeed!" << std::endl;
}
return 0;
}
int main(int argc, char** argv) {
if (argc < 2) {
std::cerr << "[ERROR] usage: ./" << argv[0] << " naive_buffer_model_dir\n";
exit(1);
}
std::string model_dir = argv[1];
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc;
int i;
for( i=0; i < NUM_THREADS; i++ ){
std::cout <<"main() : creating thread, " << i << std::endl;
td[i].thread_id = i;
td[i].message = (char*)"This is message";
rc = pthread_create(&threads[i], NULL,
RunModel, NULL);
if (rc){
std::cout << "Error:unable to create thread," << rc << std::endl;
exit(-1);
}
}
pthread_exit(NULL);
return 0;
}
【Reason】CreatePaddlePredictor
method is not safe for multi-thread condition. Further more, we have located that inside optimizer->GenRuntimeProgram()
has caused this problem.
【Effect of Current PR】
Add thread lock to CreatePaddlePredictor
, so that CreatePaddlePredictor
method will be operated sequently in multi-thread program to avoid unknown error.