Я разрабатываю многопоточную программу, которая читает базу данных mysql за 10 потоков и выводит результат в виде количества строк в каждом потоке. Таким образом, конечный результат - 100 строк в командной строке. проблема в том, что когда я запускаю его, иногда выдает ошибку: Can't connect to MySQL server on 'localhost' (111) иногда он возвращает segmentation fault(core dumped). Я проверил потоки, и они также создаются нормально, без ошибок.

Когда я создаю только один поток, он отлично работает, давая ожидаемый результат. No of Rows of 00 - 6

Другое дело, что я запускаю это на сервере Red Hat, и он работает хорошо, без ошибок, но счетчик неправильный. Я создал 5 потоков, и для первого потока 52380 правильный, но для других он дает другой результат результат должно получиться вот так

No of Rows  of 00 - 52380
No of Rows  of 01 - 53434
No of Rows  of 02 - 53333
No of Rows  of 03 - 50005
No of Rows  of 04 - 48393

Но фактический результат таков

No of Rows  of 00 - 52380
No of Rows  of 00 - 52380
No of Rows  of 01 - 52380
No of Rows  of 01 - 52380
No of Rows  of 01 - 52380

Я компилирую это, используя

gcc main.c -lpthread `mysql_config --cflags --libs`

Что могло бы быть причиной этой проблемы. Может ли кто-нибудь помочь мне с этим, пожалуйста. Вот код, который я использовал. Заголовочный файл здесь не приводится. Он содержит детали базы данных.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main1.h"
#include <pthread.h>
#include <mysql/mysql.h>
#include <mysql/my_global.h>

int main(int argc, char** argv) {

   int threadRet[10], i = 0;
   pthread_t * threadT = (pthread_t *) malloc(10 * sizeof (pthread_t));

   for (i = 0; i < 10; i++) {
        threadRet[i] = pthread_create(&threadT[i], NULL, threadedConnection, &i);
        printf("thread %d - thread ret %d\n",i,threadRet[i]);
   }
   i = 0;
   for (i = 0; i < 10; i++) {
        pthread_join(threadT[i], NULL);
   }
   return (EXIT_SUCCESS);
 }



void * threadedConnection(void * parr) {

    int * j = (int *) parr;
    int tableNo=*j;
    long int rowCount = 0;
    long int totalInserts = 0;

    MYSQL *con1 = mysql_init(NULL);
    MYSQL_RES *result;
    MYSQL_ROW row;
    con1[tableNo] = mysql_init(NULL);
    if (mysql_real_connect(con1, dataBase1[0], dataBase1[1], dataBase1[2], dataBase1[3], 0, NULL, 0) == NULL) {
        fprintf(stderr, "%s\n", mysql_error(con1));
        mysql_close(con1);
        exit(1);
     }

     char countQuery[70];
     sprintf(countQuery, "SELECT COUNT(*) FROM numberTable where number like '%s%.2d'", "%", *tableNo);

     if (mysql_query(con1[tableNo], countQuery)) {
        fprintf(stderr, "%s\n", mysql_error(con1));
        mysql_close(con1);
        exit(1);
     }

     result = mysql_store_result(con1);       //Counting
     row = mysql_fetch_row(result[tableNo]);  //line
     rowCount = strtol((row)[0], NULL, 10);   //numbers
     totalInserts = rowCount;                 //numberTable
     mysql_free_result(result[tableNo]);

     printf("No of Rows  of %.2d - %ld\n", tableNo, totalInserts);



     mysql_close(con1[tableNo]);
     }
1
Laksith 30 Дек 2015 в 07:44

2 ответа

Лучший ответ

Мне пришлось пройти через действительно сложную ситуацию, чтобы наконец добраться до сути. Это было настолько просто, что достаточно было всего одного объявления массива. В моем коде в main function. при создании потоков, которые я использовал,

for (i = 0; i < 10; i++) {
    threadRet[i] = pthread_create(&threadT[i], NULL, threadedConnection, &i);
    printf("thread %d - thread ret %d\n",i,threadRet[i]);
}

Вот ссылка на антора, в которой говорится об этом Pthreads

Дело в том, что когда массивы выполняют свою работу, они используют переданное целое число i, и поскольку адрес целого числа передается и в цикле for он непрерывно увеличивает свое значение. Поэтому, когда потоки пытаются использовать его, он уже увеличивается и постоянно увеличивается. так что он застрял.

Чтобы преодолеть это, я объявил массив

 for (i = 0; i < threadCount; i++) {
    tbl[i] = i;
 }
 i == 0;

И элементы этого массива были переданы при создании потоков как

 for (i = 0; i < 10; i++) {
    threadRet[i] = pthread_create(&threadT[i], NULL, threadedConnection, &tbl[i]);
    printf("thread %d - thread ret %d\n",i,threadRet[i]);
 }

Это хорошо сработало. Да и модификаций стало меньше. которые я не упомянул здесь, потому что считаю, что они не связаны с моей проблемой. они есть при объединении потоков в конце основного, я использовал pthread_attr, чтобы сделать их соединяемыми, иначе это было не совсем правильно. так что вот окончательный код только (здесь приведена основная функция, поскольку изменения были внесены только в основную)

int main(int argc, char** argv) {

    int threadRet, i = 0;
    int tbl[threadCount];
    void *status;
    pthread_attr_t attr;

    for (i = 0; i < threadCount; i++) {
    tbl[i] = i;
    }
    i == 0;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    pthread_t * threadT = (pthread_t *) malloc(threadCount * sizeof (pthread_t));

    for (i = 0; i < threadCount; i++) {
    threadRet = pthread_create(&threadT[i], &attr, threadedConnection, &tbl[i]);
        if (threadRet) {
            printf("Error creating thread return value of pthread_create() is %d", threadRet);
        }
        printf("thread %d - thread ret %d\n", i, threadRet);
    }
    i = 0;

    pthread_attr_destroy(&attr);

    for (i = 0; i < threadCount; i++) {
        threadRet = pthread_join(threadT[i], &status);
        if (threadRet) {
            printf("Error joining thread return value of pthread_join() is %d", threadRet);
        }

    }

    free(threadT);
    pthread_exit(NULL);
    return (EXIT_SUCCESS);
}

Спасибо всем, кто пытался помочь потратить свое время ....

1
Laksith 29 Авг 2019 в 05:22

В

if (mysql_real_connect(con1, dataBase1[0], dataBase1[1], dataBase1[2], dataBase1[3], 0, NULL, 0) == NULL) {
          ^ port

Вам необходимо передать порт, который по умолчанию равен 3306. Проверьте имя хоста и другие параметры.

См. http://dev.mysql.com/doc/ refman / 5.7 / en / mysql-real-connect.html для справки.

0
doptimusprime 30 Дек 2015 в 04:51