ошибка многопоточного доступа MySQL

0

Я написал простую многопоточную программу C для доступа к MySQL, она отлично работает, кроме , когда Я добавляю функцию usleep() или sleep() в каждую функцию потока. Я создал два pthreads в основном методе,

int main(){
        mysql_library_init(0,NULL,NULL);
        printf("Hello world!\n");
        init_pool(&p,100);
        pthread_t producer;
        pthread_t consumer_1;
        pthread_t consumer_2;
        pthread_create(&producer,NULL,produce_fun,NULL);
        pthread_create(&consumer_1,NULL,consume_fun,NULL);
        pthread_create(&consumer_2,NULL,consume_fun,NULL);
        mysql_library_end();
}



   void * produce_fun(void *arg){
    pthread_detach(pthread_self());
    //procedure
    while(1){
        usleep(500000);
        printf("producer...\n");
        produce(&p,cnt++);
    }
    pthread_exit(NULL);
}

void * consume_fun(void *arg){
    pthread_detach(pthread_self());
    MYSQL db;
    MYSQL *ptr_db=mysql_init(&db);
    mysql_real_connect();

    //procedure
    while(1){
        usleep(1000000);
        printf("consumer...");
        int item=consume(&p);
        addRecord_d(ptr_db,"test",item);
    }
    mysql_thread_end();
    pthread_exit(NULL);
}

void addRecord_d(MYSQL *ptr_db,const char *t_name,int item){
    char query_buffer[100];
    sprintf(query_buffer,"insert into %s values(0,%d)",t_name,item);
//pthread_mutex_lock(&db_t_lock);
    int ret=mysql_query(ptr_db,query_buffer);
    if(ret){
        fprintf(stderr,"%s%s\n","cannot add record to ",t_name);
        return;
    }

    unsigned long long update_id=mysql_insert_id(ptr_db);
//    pthread_mutex_unlock(&db_t_lock);
    printf("add record (%llu,%d) ok.",update_id,item);
}

выводить ошибки программы, например:

[Thread debugging using libthread_db enabled]
[New Thread 0xb7ae3b70 (LWP 7712)]
Hello world!
[New Thread 0xb72d6b70 (LWP 7713)]
[New Thread 0xb6ad5b70 (LWP 7714)]
[New Thread 0xb62d4b70 (LWP 7715)]
[Thread 0xb7ae3b70 (LWP 7712) exited]
producer...
producer...
consumer...consumer...add record (31441,0) ok.add record (31442,1) ok.producer...
producer...
consumer...consumer...add record (31443,2) ok.add record (31444,3) ok.producer...
producer...
consumer...consumer...add record (31445,4) ok.add record (31446,5) ok.producer...
producer...
consumer...consumer...add record (31447,6) ok.add record (31448,7) ok.producer...
Error in my_thread_global_end(): 2 threads didn't exit
[Thread 0xb72d6b70 (LWP 7713) exited]
[Thread 0xb6ad5b70 (LWP 7714) exited]
[Thread 0xb62d4b70 (LWP 7715) exited]

Program exited normally.

, и когда я добавляю pthread_mutex_lock в функцию addRecord_d, ошибка все еще существует. Так в чем же проблема?

Теги:
multithreading
pthreads

2 ответа

1

Проблема в том, что вы слишком рано вызываете mysql_library_end() (особенно с помощью usleep() в потоках). Можно закончить основной поток и продолжить работу других потоков, но это не рекомендуется. Ваше решение добавить pthread_join() является лучшим. Вы также можете устранить mysql_library_end(), и он будет работать.

0

Пока ваши потоки производителей и потребителей спят, они удерживают соединения mysql, которые открыты для продолжительности соответствующих функций.

Когда программа пытается закончить, скорее всего, эти потоки спали и не могут получить сигнал завершения. Следовательно, ошибка от my_thread_global_end().

У меня сейчас нет доступа к среде dev, поэтому я не могу попробовать ваш образец. Но я думаю, что это может пройти мимо ошибки, хотя это был бы очень неэффективный код (образец из функции consume_fun):

//procedure
while(1){
    usleep(1000000);

    MYSQL *ptr_db=mysql_init(&db);
    mysql_real_connect();

    printf("consumer...");
    int item=consume(&p);
    addRecord_d(ptr_db,"test",item);

    mysql_thread_end();
}

В двух словах вышеприведенный образец должен заставить соединение быть установленным и закрытым вне цикла сна. Я не думаю, что это лучший код, но для целей иллюстрации это должно избавиться от ошибок.

Имейте в виду: это заставит вас открывать и закрывать соединения в цикле, что будет крайне неэффективным использованием ресурсов в среде "производственного" типа, поэтому не делайте этого в реальной жизни.:)

Надеюсь, что это поможет.

  • 0
    Привет, Майк, спасибо за помощь. Когда я заменяю соответствующий код на тот, который вы указали выше, четыре потока создаются и существуют в ближайшее время, вывод - просто «привет мир». поэтому я думаю, что в методе main может быть какая-то ошибка, на самом деле, я забыл добавить метод join, поэтому я рискую завершить метод main, пока остальные три потока еще живы. Добавьте pthread_join () в конец метода main, ошибка больше не будет возникать. Ну, я новичок в многопоточном программировании, и ваш ответ напоминает мне о методе объединения, спасибо.
  • 0
    Что ж, я пытаюсь воспользоваться вашим советом по поводу моего другого тестового источника, но как только он запустит mysql сказал "Слишком много соединений", у вас есть идея получше, чем эта?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню