Advertisement
gametwix

Untitled

Feb 28th, 2021
1,420
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.26 KB | None | 0 0
  1. /*
  2. Лабораторная работа №3 по курсу "Операционные системы"
  3. Задание: Перемножение двух матриц с использованием потоков, потоки синхронезировать при помощи mutex.
  4. */
  5.  
  6.  
  7. #define _POSIX_C_SOURCE 199309L
  8. #include <stdio.h>
  9. #include <time.h>
  10. #include <stdlib.h>
  11. #include <pthread.h>
  12. #include <memory.h>
  13.  
  14.  
  15. // Global variables
  16. #define NUM_OF_THREADS 100
  17. pthread_mutex_t mut;
  18. // size of matrix
  19. static int A, B, C, D;
  20. // Determinate the element result's matrix
  21. static int string = -1;
  22. static int column = 0;
  23. // counter for pthread
  24. static int count = 0;
  25.  
  26. // Struct for complex number representation
  27. typedef struct Complex{
  28.     int real;
  29.     int imaginary;
  30. } Complex;
  31.  
  32. typedef struct Param{
  33.     void* myData;
  34.     int sizeColomn;
  35.     int *Str;
  36.     int numStr;
  37. } Param;
  38.  
  39. // Struct with for pointers on three matriсes
  40. typedef struct Data{
  41.     Complex** matrix1;
  42.     Complex** matrix2;
  43.     Complex** result;
  44. } Data;
  45.  
  46. // The function, which will be transmitted in the threads
  47. void* Produce(int str,int col,void* ptr){
  48.     Data* myData = (Data*) ptr;
  49.     for (int k = 0; k < B; ++k){
  50.         myData->result[str][col].real += myData->matrix1[str][k].real*myData->matrix2[k][col].real - myData->matrix1[str][k].imaginary*myData->matrix2[k][col].imaginary;
  51.         myData->result[str][col].imaginary += myData->matrix1[str][k].real*myData->matrix2[k][col].imaginary + myData->matrix1[str][k].imaginary*myData->matrix2[k][col].real;
  52.     }
  53.     return NULL;
  54. }
  55.  
  56. void* thread_mission(Param* Param){
  57.     for(int i = 0; i < Param->numStr;++i){
  58.         for(int j = 0; j < Param->sizeColomn;++j){
  59.             Produce(Param->Str[i],j,Param->myData);
  60.         }
  61.     }
  62.        
  63.     return NULL;
  64. }
  65.  
  66. int main(int argc, char* argv[]){
  67.  
  68.     struct timespec start, finish;
  69.  
  70.     if (argc != 2) {
  71.         printf("Syntax: ./main Number_of_threads\n");
  72.         return 1;
  73.     }
  74.  
  75.     // restrictions from above for threads
  76.     int num = atoi(argv[1]);
  77.     if(*argv[1] > NUM_OF_THREADS){
  78.         num = NUM_OF_THREADS;
  79.     }
  80.    
  81.     // Create array variables for threads
  82.     pthread_t* threads = (pthread_t*)calloc(num, sizeof(pthread_t));
  83.     if (threads == NULL) {
  84.         printf("Can't allocate space for threads\n");
  85.         return 2;
  86.     }
  87.  
  88.     // Sizes of two matrices
  89.     printf("Enter first matrix size:\n");
  90.     scanf("%d %d", &A, &B);
  91.     printf("Enter second matrix size:\n");    
  92.     scanf("%d %d", &C, &D);
  93.    
  94.     if(B != C){
  95.         printf("It is impossible to multiply matrices!\n");
  96.         return -1;
  97.     }
  98.     // Stracut for transmitted data in thread
  99.     Data* myData = (Data*) malloc(sizeof(Data));
  100.    
  101.     // Initialization
  102.     myData[0].matrix1 = (Complex**) malloc(sizeof(Complex*)*A);
  103.     for(int i = 0; i < A; ++i){
  104.         myData[0].matrix1[i] = (Complex*) malloc(sizeof(Complex)*B);
  105.     }
  106.  
  107.     myData[0].matrix2 = (Complex**) malloc(sizeof(Complex*)*C);
  108.     for(int i = 0; i < C; ++i){
  109.         myData[0].matrix2[i] = (Complex*) malloc(sizeof(Complex)*D);
  110.     }
  111.  
  112.     myData[0].result = (Complex**) malloc(sizeof(Complex*)*A);
  113.     for(int i = 0; i < A; ++i){
  114.         myData[0].result[i] = (Complex*) malloc(sizeof(Complex)*D);
  115.     }
  116.  
  117.  
  118.     // filling the arrays
  119.     printf("Enter the first matrix:\n");
  120.     for(int i = 0; i < A; ++i){
  121.         for(int j = 0; j < B; ++j){
  122.             scanf("%d", &myData->matrix1[i][j].real);
  123.             scanf("%d",&myData->matrix1[i][j].imaginary);
  124.         }
  125.     }
  126.  
  127.     printf("Enter the second matrix:\n");
  128.     for(int i = 0; i < C; ++i){
  129.         for(int j = 0; j < D; ++j){
  130.             scanf("%d", &myData->matrix2[i][j].real);
  131.             scanf("%d",&myData->matrix2[i][j].imaginary);
  132.         }
  133.     }
  134.  
  135.     for(int i = 0; i < A; ++i){
  136.         for(int j = 0; j < D; ++j){
  137.             myData->result[i][j].real = (int) 0;
  138.             myData->result[i][j].imaginary = (int) 0;
  139.         }
  140.     }
  141.    
  142.     printf("First matrix:\n");
  143.     for(int i = 0; i < A; ++i){
  144.         for(int j = 0; j < B; ++j){
  145.             if(myData->matrix1[i][j].imaginary >= 0)
  146.                 printf("%d+%d*i ", myData->matrix1[i][j].real, myData->matrix1[i][j].imaginary);
  147.             if(myData->result[i][j].imaginary < 0)
  148.                 printf("%d-%d*i ", myData->matrix1[i][j].real, myData->matrix1[i][j].imaginary);
  149.         }
  150.         printf("\n");
  151.     }
  152.  
  153.     printf("Second matrix:\n");
  154.     for(int i = 0; i < C; ++i){
  155.         for(int j = 0; j < D; ++j){
  156.             if(myData->matrix2[i][j].imaginary >= 0)
  157.                 printf("%d+%d*i ", myData->matrix2[i][j].real, myData->matrix2[i][j].imaginary);
  158.             else
  159.                 printf("%d-%d*i ", myData->matrix2[i][j].real, myData->matrix2[i][j].imaginary);
  160.         }
  161.         printf("\n");
  162.     }
  163.  
  164.     clock_gettime(CLOCK_MONOTONIC, &start);
  165.     pthread_mutex_init(&mut, NULL);
  166.  
  167.  
  168.     // create threads
  169.     Param P[num];
  170.     for(int i = 0;i<num;++i){
  171.         P[i].numStr = 0;
  172.         P[i].Str = NULL;
  173.         P[i].myData = myData;
  174.         P[i].sizeColomn = D;
  175.     }
  176.     for(int i = 0;i<A;++i){
  177.         P[i%num].numStr+=1;
  178.         P[i%num].Str = realloc(P[i%num].Str,P[i%num].numStr*sizeof(int));
  179.         P[i%num].Str[P[i%num].numStr - 1] = i;
  180.     }
  181.     for(int j = 0; j < num; ++j){
  182.         pthread_create(&threads[j], NULL,(void*) &thread_mission, &P[j]);  
  183.     }
  184.    
  185.  
  186.     for (int i = 0; i < num; i++)
  187.         pthread_join(threads[i], NULL);
  188.     clock_gettime(CLOCK_MONOTONIC, &finish);
  189.  
  190.     printf("Result matrix:\n");
  191.     for(int i = 0; i < A; ++i){
  192.         for(int j = 0; j < D; ++j){
  193.             if(myData->result[i][j].imaginary >= 0)
  194.                 printf("%d+%d*i ", myData->result[i][j].real, myData->result[i][j].imaginary);
  195.             else
  196.                 printf("%d%d*i ", myData->result[i][j].real, myData->result[i][j].imaginary);
  197.         }
  198.         printf("\n");
  199.     }
  200.    
  201.    
  202.    
  203.     double elapsed = (finish.tv_sec - start.tv_sec);
  204.     elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
  205.     pthread_mutex_destroy(&mut);
  206.     printf("Time: %.4f seconds\n", elapsed);
  207.    
  208.     free(myData->matrix1);
  209.     free(myData->matrix2);
  210.     free(myData->result);
  211.     free(myData);
  212.     return 0;
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement