Guest User

Untitled

a guest
Jun 3rd, 2012
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. int thread_quantity;
  2. int buffer_size;
  3. char *requested_file_name;
  4. char *requested_word;
  5.  
  6. int file_des = 0;
  7. int created_threads = 0;
  8. int alive_threads;
  9.  
  10. pthread_mutex_t reading_mutex = PTHREAD_MUTEX_INITIALIZER;
  11. pthread_t *thread_id = NULL;
  12. off_t file_size;
  13. pthread_key_t buffer;
  14.  
  15. void usage() {
  16. exit(1);
  17. }
  18. void err_exit(char *);
  19. void* thread_function(void *);
  20. void clean_thread(void *);
  21. void clean_tsd_buffer(void *); //thread specific data
  22. //############################################################
  23. int main(int argc, char *argv[]) {
  24.     int i;
  25.     if (argc != 5) {
  26.         usage();
  27.     } else {
  28.         thread_quantity = (int) strtol(argv[1], NULL, 10);
  29.         alive_threads = thread_quantity;
  30.         thread_id = malloc(sizeof(pthread_t) * thread_quantity);
  31.         requested_file_name = argv[2];
  32.         buffer_size = (int) strtol(argv[3], NULL, 10);
  33.         if (errno) {
  34.             usage();
  35.         }
  36.         requested_word = argv[4];
  37.     }
  38.     if ((file_des = open(requested_file_name, O_RDONLY)) == -1) {
  39.         err_exit("Error: open(requested_file_name)");
  40.     }
  41.     if ((file_size = lseek(file_des, 0, SEEK_END)) == (off_t) -1) {
  42.         err_exit("Error: lseek(file_des, 0, SEEK_END)");
  43.     }
  44.     if (lseek(file_des, 0, SEEK_SET) == (off_t) -1) {
  45.         err_exit("Error: lseek(file_des, 0, SEEK_END)");
  46.     }
  47.     if (pthread_mutex_init(&reading_mutex, NULL) != 0) {
  48.         err_exit("Error: pthread_mutex_init(reading_mutex)");
  49.     }
  50.     if (pthread_key_create(&buffer, clean_tsd_buffer)) {
  51.         err_exit("Error: pthread_key_create()");
  52.     }
  53.     //=========================================================
  54.     for (i = 0; i < thread_quantity; i++) {
  55.         if (pthread_create(&thread_id[i], NULL, thread_function, NULL)) {
  56.             err_exit("Error: pthread_create()");
  57.         } else {
  58.             created_threads++;
  59.         }
  60.     }
  61.     while (alive_threads) {
  62.         usleep(1000);
  63.     }
  64.     for (i = 0; i < thread_quantity; i++) {
  65.         if (pthread_join(thread_id[i], NULL)) {
  66.             err_exit("Error: pthread_join()");
  67.         }
  68.     }
  69.     //=========================================================
  70.     err_exit(NULL);
  71.     return EXIT_SUCCESS;
  72. }
  73. //############################################################
  74. void clean_tsd_buffer(void *arg) {
  75.     if (arg != NULL) {
  76.         free(arg);
  77.     }
  78. }
  79. void clean_thread(void *arg) {
  80.     alive_threads--;
  81. }
  82. //-----------------------------------------------------------
  83. void *thread_function(void *data) {
  84.     pthread_cleanup_push(clean_thread, NULL);
  85.                 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
  86.                     err_exit("Error: pthread_setcanceltype()");
  87.                 }
  88.                 if (pthread_setspecific(buffer, malloc(sizeof(char) * buffer_size))) {
  89.                     err_exit("Error: pthread_setspecific()");
  90.                 }
  91.                 int i, bytes_readed;
  92.                 off_t jump, current_offset;
  93.                 void *cbuffer = pthread_getspecific(buffer);
  94.                 for (i = 0; i < thread_quantity; i++) {
  95.                     if (pthread_equal(pthread_self(), thread_id[i])) {
  96.                         jump = (off_t) i * buffer_size;
  97.                         break;
  98.                     }
  99.                 }
  100.                 //==========================================================
  101.                 while (1) {
  102.                     if (pthread_mutex_lock(&reading_mutex) != 0) {
  103.                         err_exit("Error: pthread_mutex_lock(reading_mutex)");
  104.                     }
  105.                     if ((current_offset = lseek(file_des, jump, SEEK_SET)) == (off_t) -1) {
  106.                         err_exit("Error: lseek(reading_mutex)");
  107.                     }
  108.                     if (current_offset > file_size) {
  109.                         if (pthread_mutex_unlock(&reading_mutex) != 0) {
  110.                             err_exit("Error: pthread_mutex_unlock(reading_mutex)");
  111.                         }
  112.                         if (pthread_cancel(pthread_self())) {
  113.                             err_exit("Error: pthread_cancel()");
  114.                         }
  115.                     } else {
  116.                         bytes_readed = read(file_des, cbuffer, buffer_size);
  117.                     }
  118.                     if (pthread_mutex_unlock(&reading_mutex) != 0) {
  119.                         err_exit("Error: pthread_mutex_unlock(reading_mutex)");
  120.                     }
  121.                     usleep(50);
  122.                     if (bytes_readed > 0) {
  123.                         //no, don't need that code
  124.                     } else if (!bytes_readed) {
  125.                         if (pthread_cancel(pthread_self())) {
  126.                             err_exit("Error: pthread_cancel()");
  127.                         }
  128.                     } else { // Error
  129.                         err_exit("Error: czytanie z pliku w wÄ…tku");
  130.                     }
  131.                     jump += thread_quantity * buffer_size;
  132.                 }
  133.                 //==========================================================
  134.                 pthread_cleanup_pop(1);
  135.     if (pthread_cancel(pthread_self())) {
  136.         err_exit("Error: pthread_cancel()");
  137.     }
  138.     return data;
  139. }
  140. //-----------------------------------------------------------
  141. void err_exit(char *msg) {
  142.     if (msg != NULL) {
  143.         perror(msg);
  144.         sleep(10);
  145.     }
  146.     if (file_des != 0) {
  147.         if (close(file_des) == -1) {
  148.             perror("Error: close(file_des)");
  149.         }
  150.     }
  151.     if (thread_id != NULL) {
  152.         free(thread_id);
  153.     }
  154.     exit(1);
  155. }
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162. /////////////////////////////////////####################### test.txt #################
  163. The pthread_cleanup_push() function pushes routine onto the top of  the
  164.        stack  of clean-up handlers.  When routine is later invoked, it will be
  165.        given arg as its clean argument.
  166.        The pthread_cleanup_pop() function removes the routine at  the  top  of
  167.        the  stack  of clean-up handlers, and optionally executes it if execute
  168.        is nonzero.
  169.  
  170.        A cancellation clean-up handler is popped from the stack  and  executed
  171.        in the following circumstances:
  172.  
  173.        1. When  a thread is canceled, all of the stacked clean-up handlers are
  174.           popped and executed in the reverse of the order in which  they  were
  175.           pushed onto the stack.
  176.  
  177.        2. When  a  thread  terminates by calling pthread_exit(3), all clean-up
  178.           handlers are executed as described in the preceding point.   (Clean-
  179.           up  handlers are not called if the thread terminates by performing a
  180.           return from the thread start function.) clean
  181.  
  182.        3. When a thread calls pthread_cleanup_pop()  with  a  nonzero  execute
  183.           argument, the top-mst clean-up handler is popped and executed.
  184.  
  185.        POSIX.1  permits pthread_cleanup_push() and pthread_cleanup_pop() to be
  186.        implemented as macros that expand  to  text  containing  '{'  and  '}',
  187.        respectively.   For  this  reason, the caller must ensure that call
Advertisement
Add Comment
Please, Sign In to add comment