thread_test.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:7k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <my_global.h>
  14. #ifndef THREAD
  15. int main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
  16. {
  17.   printf("This test must be compiled with multithread support to workn");
  18.   exit(1);
  19. }
  20. #else
  21. #include <my_sys.h>
  22. #include <my_pthread.h>
  23. #include "mysql.h"
  24. #include <my_getopt.h>
  25. static my_bool version, verbose, tty_password= 0;
  26. static uint thread_count,number_of_tests=1000,number_of_threads=2;
  27. static pthread_cond_t COND_thread_count;
  28. static pthread_mutex_t LOCK_thread_count;
  29. static char *database,*host,*user,*password,*unix_socket,*query;
  30. uint tcp_port;
  31. #ifndef __WIN__
  32. void *test_thread(void *arg __attribute__((unused)))
  33. #else
  34. unsigned __stdcall test_thread(void *arg __attribute__((unused)))
  35. #endif
  36. {
  37.   MYSQL *mysql;
  38.   uint count;
  39.   mysql=mysql_init(NULL);
  40.   if (!mysql_real_connect(mysql,host,user,password,database,tcp_port,
  41.   unix_socket,0))
  42.   {
  43.     fprintf(stderr,"Couldn't connect to engine!n%snn",mysql_error(mysql));
  44.     perror("");
  45.     goto end;
  46.   }
  47.   if (verbose) { putchar('*'); fflush(stdout); }
  48.   for (count=0 ; count < number_of_tests ; count++)
  49.   {
  50.     MYSQL_RES *res;
  51.     if (mysql_query(mysql,query))
  52.     {
  53.       fprintf(stderr,"Query failed (%s)n",mysql_error(mysql));
  54.       goto end;
  55.     }
  56.     if (!(res=mysql_store_result(mysql)))
  57.     {
  58.       fprintf(stderr,"Couldn't get result from %sn", mysql_error(mysql));
  59.       goto end;
  60.     }
  61.     mysql_free_result(res);
  62.     if (verbose) { putchar('.'); fflush(stdout); }
  63.   }
  64. end:
  65.   if (verbose) { putchar('#'); fflush(stdout); }
  66.   mysql_close(mysql);
  67.   pthread_mutex_lock(&LOCK_thread_count);
  68.   thread_count--;
  69.   VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
  70.   pthread_mutex_unlock(&LOCK_thread_count);
  71.   pthread_exit(0);
  72.   return 0;
  73. }
  74. static struct my_option my_long_options[] =
  75. {
  76.   {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
  77.    0, 0, 0, 0, 0},
  78.   {"database", 'D', "Database to use", (gptr*) &database, (gptr*) &database,
  79.    0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  80.   {"host", 'h', "Connect to host", (gptr*) &host, (gptr*) &host, 0, GET_STR,
  81.    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  82.   {"password", 'p',
  83.    "Password to use when connecting to server. If password is not given it's asked from the tty.",
  84.    0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
  85.   {"user", 'u', "User for login if not current user", (gptr*) &user,
  86.    (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  87.   {"version", 'V', "Output version information and exit",
  88.    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  89.   {"verbose", 'v', "Write some progress indicators", (gptr*) &verbose,
  90.    (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
  91.   {"query", 'Q', "Query to execute in each threads", (gptr*) &query,
  92.    (gptr*) &query, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  93.   {"port", 'P', "Port number to use for connection", (gptr*) &tcp_port,
  94.    (gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0},
  95.   {"socket", 'S', "Socket file to use for connection", (gptr*) &unix_socket,
  96.    (gptr*) &unix_socket, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  97.   {"test-count", 'c', "Run test count times (default %d)",
  98.    (gptr*) &number_of_tests, (gptr*) &number_of_tests, 0, GET_UINT,
  99.    REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
  100.   {"thread-count", 't', "Number of threads to start",
  101.    (gptr*) &number_of_threads, (gptr*) &number_of_threads, 0, GET_UINT,
  102.    REQUIRED_ARG, 2, 0, 0, 0, 0, 0},
  103.   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
  104. };
  105. static const char *load_default_groups[]= { "client",0 };
  106. static void usage()
  107. {
  108.   printf("Connection to a mysql server with multiple threadsn");
  109.   if (version)
  110.     return;
  111.   puts("This software comes with ABSOLUTELY NO WARRANTY.n");
  112.   printf("Usage: %s [OPTIONS] [database]n", my_progname);
  113.   my_print_help(my_long_options);
  114.   print_defaults("my",load_default_groups);
  115.   my_print_variables(my_long_options);
  116.   printf("nExample usage:nn
  117. %s -Q 'select * from mysql.user' -c %d -t %dn",
  118.  my_progname, number_of_tests, number_of_threads);
  119. }
  120. static my_bool
  121. get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
  122.        char *argument)
  123. {
  124.   switch (optid) {
  125.   case 'p':
  126.     if (argument)
  127.     {
  128.       my_free(password, MYF(MY_ALLOW_ZERO_PTR));
  129.       password= my_strdup(argument, MYF(MY_FAE));
  130.       while (*argument) *argument++= 'x'; /* Destroy argument */
  131.     }
  132.     else
  133.       tty_password= 1;
  134.     break;
  135.   case 'V':
  136.     version= 1;
  137.     usage();
  138.     exit(0);
  139.     break;
  140.   case '?':
  141.   case 'I': /* Info */
  142.     usage();
  143.     exit(1);
  144.     break;
  145.   }
  146.   return 0;
  147. }
  148. static void get_options(int argc, char **argv)
  149. {
  150.   int ho_error;
  151.   load_defaults("my",load_default_groups,&argc,&argv);
  152.   if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
  153.     exit(ho_error);
  154.   free_defaults(argv);
  155.   if (tty_password)
  156.     password=get_tty_password(NullS);
  157.   return;
  158. }
  159. int main(int argc, char **argv)
  160. {
  161.   pthread_t tid;
  162.   pthread_attr_t thr_attr;
  163.   uint i;
  164.   int error;
  165.   MY_INIT(argv[0]);
  166.   get_options(argc,argv);
  167.   if ((error=pthread_cond_init(&COND_thread_count,NULL)))
  168.   {
  169.     fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)",
  170.     error,errno);
  171.     exit(1);
  172.   }
  173.   pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
  174.   if ((error=pthread_attr_init(&thr_attr)))
  175.   {
  176.     fprintf(stderr,"Got error: %d from pthread_attr_init (errno: %d)",
  177.     error,errno);
  178.     exit(1);
  179.   }
  180.   if ((error=pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED)))
  181.   {
  182.     fprintf(stderr,
  183.     "Got error: %d from pthread_attr_setdetachstate (errno: %d)",
  184.     error,errno);
  185.     exit(1);
  186.   }
  187.   printf("Init ok. Creating %d threadsn",number_of_threads);
  188.   for (i=1 ; i <= number_of_threads ; i++)
  189.   {
  190.     int *param= &i;
  191.     if (verbose) { putchar('+'); fflush(stdout); }
  192.     pthread_mutex_lock(&LOCK_thread_count);
  193.     if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param)))
  194.     {
  195.       fprintf(stderr,"nGot error: %d from pthread_create (errno: %d) when creating thread: %in",
  196.       error,errno,i);
  197.       pthread_mutex_unlock(&LOCK_thread_count);
  198.       exit(1);
  199.     }
  200.     thread_count++;
  201.     pthread_mutex_unlock(&LOCK_thread_count);
  202.   }
  203.   printf("Waiting for threads to finnishn");
  204.   error=pthread_mutex_lock(&LOCK_thread_count);
  205.   while (thread_count)
  206.   {
  207.     if ((error=pthread_cond_wait(&COND_thread_count,&LOCK_thread_count)))
  208.       fprintf(stderr,"nGot error: %d from pthread_cond_waitn",error);
  209.   }
  210.   pthread_mutex_unlock(&LOCK_thread_count);
  211.   pthread_attr_destroy(&thr_attr);
  212.   printf("nendn");
  213.   my_end(0);
  214.   return 0;
  215.   exit(0);
  216.   return 0; /* Keep some compilers happy */
  217. }
  218. #endif /* THREAD */