I am developing a threaded program which reads a mysql database in 10 threads and print the result as a row count by each thread. So the final result is 100 line counts on the command line. the problem is when I run it it sometimes gives an error saying Can't connect to MySQL server on 'localhost' (111)
sometimes it returns a segmentation fault(core dumped)
I checked the threads and they are also created fine with no errors.
when I create only one thread it works perfectly fine giving the expected output. No of Rows of 00 - 6
Another thing is I run this in a red hat server and It works well with no errors but the count is wrong.I created 5 threads and for the first thread 52380
is correct but for others it gives a different result the result should come like this
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
but the actual result coming out is this
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
I compile this using
gcc main.c -lpthread `mysql_config --cflags --libs`
What would be the cause for this problem. Can anyone help me with this please. Down here is the code I used. Header file is not given here. It contains the database details.
#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]);
}
I had to go throgh a really tough situation to finally get to the point. It was so simple that Only a single array declaration would do the thing. In my code , in the main function. when creating threads I've used,
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]);
}
Here is anthor link which says about this Pthreads
the thing is that when the arrays do their work they uses the passed integer i
and since the address of the integer is passed and in the for loop it continuously increases its value . So when threads try to use it its already incremented and continuously increased. so it gets jammed.
So to overcome it what I did was I declared an array
for (i = 0; i < threadCount; i++) {
tbl[i] = i;
}
i == 0;
and this arrays elements were passed when creating the threads as
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]);
}
this did the work well. And there were also some fewer modifications. that I didn't mention here because I believe they are not related to my problem. they are when joining threads in the end of the main , I used a pthread_attr
to make them joinable other wise it wasn't quite right . so here is the final code only the (main function is given here since changes were taken place only in the main)
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);
}
thanks anyone who tried to help out contributing their time....
In
if (mysql_real_connect(con1, dataBase1[0], dataBase1[1], dataBase1[2], dataBase1[3], 0, NULL, 0) == NULL) {
^ port
You need to pass the port which is default to 3306. Check for the host name and other parameter.
See http://dev.mysql.com/doc/refman/5.7/en/mysql-real-connect.html for reference.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.