Advertisement
Guest User

Govno

a guest
Nov 13th, 2019
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.20 KB | None | 0 0
  1. // Lab2.cpp : This file contains the 'main' function. Program execution begins and ends there.
  2. //
  3.  
  4. #include <iostream>
  5. #include <pthread.h>
  6. #include <fstream>
  7. #include <string>
  8. #include <vector>
  9. #include <queue>
  10. #include <Windows.h>
  11. #include <chrono>
  12.  
  13. #pragma comment (lib, "pthreadVCE2.lib")
  14. #pragma warning (disable : 4996)
  15.  
  16. pthread_mutex_t mutex;
  17. pthread_mutex_t end_mutex;
  18. bool end = false;
  19.  
  20. auto factorize(const int number) -> std::vector<int>
  21. {
  22.     auto result = std::vector<int>();
  23.     auto cur_number = number;
  24.     auto probe = 2;
  25.  
  26.     while (cur_number != 1)
  27.     {
  28.         if (cur_number % probe != 0)
  29.             probe++;
  30.         else
  31.         {
  32.             cur_number /= probe;
  33.             result.push_back(probe);
  34.         }
  35.     }
  36.  
  37.     return result;
  38. }
  39.  
  40. auto string_to_char_array(const std::string& source) -> char*
  41. {
  42.     const auto destination = new char[source.size() + 1];
  43.     source.copy(destination, source.size() + 1);
  44.     destination[source.size()] = '\0';
  45.  
  46.     return destination;
  47. }
  48.  
  49. auto array_to_vector(const int* buffer, const int size) -> std::vector<int>
  50. {
  51.     std::vector<int> vec(size);
  52.  
  53.     for (auto i = 0; i < size; i++)
  54.     {
  55.         vec[i] = *(buffer + i);
  56.     }
  57.  
  58.     return vec;
  59. }
  60.  
  61. typedef struct
  62. {
  63.     std::queue<std::vector<int>>* q;
  64.     long tid;
  65.     pthread_mutex_t* queue_mutex;
  66. } evaluator_params;
  67.  
  68. auto write_numbers(const std::vector<int>& numbers, std::ofstream& stream) -> void
  69. {
  70.  
  71.     for (auto n : numbers)
  72.     {
  73.         stream << n << " = ";
  74.  
  75.         auto result = factorize(n);
  76.         for (auto number : result)
  77.         {
  78.             stream << number << " * ";
  79.         }
  80.  
  81.         stream << "\n";
  82.     }
  83. }
  84.  
  85. auto evaluate(void* params) -> void*
  86. {
  87.     auto p = static_cast<evaluator_params*>(params);
  88.     auto q = p->q;
  89.     auto path = "utils/output-" + std::to_string(p->tid) + ".txt";
  90.     auto mutex = p->queue_mutex;
  91.     std::ofstream stream(path);
  92.  
  93.     while (true)
  94.     {
  95.         if (q->empty())
  96.         {
  97.             if (end)
  98.                 return nullptr;
  99.  
  100.             continue;
  101.         }
  102.  
  103.         pthread_mutex_lock(mutex);
  104.         auto numbers = q->front();
  105.         q->pop();
  106.         pthread_mutex_unlock(mutex);
  107.  
  108.         write_numbers(numbers, stream);
  109.     }
  110. }
  111.  
  112. struct reader_params_t
  113. {
  114.     FILE* f;
  115.     int batch_size;
  116.     int index;
  117. };
  118.  
  119. auto read(void* params) -> void*
  120. {
  121.     // const auto p = static_cast<reader_params_t*>(params);
  122.     const auto p = (reader_params_t*)params;
  123.     int* buffer = new int[p->batch_size];
  124.     std::queue<std::vector<int>> q;
  125.     pthread_t tid;
  126.     pthread_mutex_t queue_mutex;
  127.  
  128.     pthread_mutex_init(&queue_mutex, nullptr);
  129.  
  130.     evaluator_params eval_params{ &q, p->index, &queue_mutex };
  131.  
  132.     pthread_create(&tid, nullptr, evaluate, &eval_params);
  133.  
  134.     while (true)
  135.     {
  136.         pthread_mutex_lock(&mutex);
  137.         const auto read_count = fread(buffer, sizeof(int), p->batch_size, p->f);
  138.         pthread_mutex_unlock(&mutex);
  139.  
  140.         auto numbers = array_to_vector(buffer, p->batch_size);
  141.  
  142.         q.push(numbers);
  143.  
  144.         if (feof(p->f))
  145.             break;
  146.     }
  147.  
  148.     pthread_mutex_lock(&end_mutex);
  149.     end = true;
  150.     pthread_mutex_unlock(&end_mutex);
  151.  
  152.     pthread_join(tid, nullptr);
  153.     return nullptr;
  154. }
  155.  
  156. class pair
  157. {
  158. private:
  159.     FILE* f;
  160.     pthread_t tid;
  161.     int index;
  162. public:
  163.     auto start(const int batch_size) -> void
  164.     {
  165.         auto p = new reader_params_t();
  166.         p->f = f;
  167.         p->batch_size = batch_size;
  168.         p->index = index;
  169.  
  170.         pthread_create(&tid, nullptr, read, p);
  171.     }
  172.     auto join() -> void
  173.     {
  174.         pthread_join(tid, nullptr);
  175.     }
  176.     auto set_file(FILE** f) -> void
  177.     {
  178.         pair::f = *f;
  179.     }
  180.     auto set_index(int i)
  181.     {
  182.         index = i;
  183.     }
  184. };
  185.  
  186.  
  187. auto test(int thread_count) -> void
  188. {
  189.     auto f = fopen("data.bin", "rb");
  190.  
  191.     const auto pairs = new pair[thread_count];
  192.  
  193.     pthread_mutex_init(&mutex, nullptr);
  194.     pthread_mutex_init(&end_mutex, nullptr);
  195.     const auto before = std::chrono::system_clock::now();
  196.     for (auto i = 0; i < thread_count; i++)
  197.     {
  198.         pairs[i].set_file(&f);
  199.         pairs[i].set_index(i);
  200.         pairs[i].start(50);
  201.     }
  202.  
  203.     for (auto i = 0; i < thread_count; i++)
  204.     {
  205.         pairs[i].join();
  206.     }
  207.     const auto after = std::chrono::system_clock::now();
  208.     const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(after - before).count();
  209.     pthread_mutex_destroy(&mutex);
  210.     pthread_mutex_init(&end_mutex, nullptr);
  211.  
  212.     printf("Number of threads: %d, Elapsed: %lld\n", thread_count, elapsed);
  213. }
  214.  
  215. auto main() -> int
  216. {
  217.     for (auto i = 1; i <= 16; i *= 2)
  218.     {
  219.         test(i);
  220.     }
  221.  
  222.     return 0;
  223. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement