Guest User

Untitled

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