Thread: Threads and Process

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    5

    Threads and Process

    Can somebody help me out?
    --------------------------------------
    Input: Square matrix A of nxn integers, where n is even.

    Rotate the elements of both diagonals in the clock direction.

    Input matrix 4x4

    1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 16

    Matrix 4x4 after rotation:

    13 2 3 1
    5 10 6 8
    9 11 7 12
    16 14 15 4

    Rotation is executed by 2n threads/processes.
    One quarter n/2 of threads/processes can
    read data from the upper half of the
    main diagonal (e.g. 4,7) and write them
    to the lower half of the secondary diagonal (e.g. 11,16).
    The second quarter of threads/processes can read data from
    the lower half of the secondary diagonal (e.g. 11,16) and
    write them to the lower half of the main diagonal (e.g. 10,13).
    The third quarter of threads/processes can read data from the
    lower half of the main diagonal (e.g. 10,13) and write them to
    the upper half of the secondary diagonal (e.g. 1,6). The last
    quarter of threads/processes can read data from the upper half of
    the secondary diagonal (e.g. 1,6) and write them to the upper
    half of the main diagonal (e.g. 4,7).

    Output: Input and output matrix.

    -------------------------------
    I've tried to begin the code so just pick out some mistakes and correct so that it can work..Thanks
    ----------------------------------
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <math.h>
    #define MAX_THREADS 100
    
    int Elmnt[10000];
    int **tmp;
    int m, n, Elmntsize, t, k, kAbs;
    pthread_mutex_t mutex;
    pthread_cond_t cond[MAX_THREADS];
    
    /////////////////////////////////////
    void Print () {
    int i;
    for(i=0; i<Elmntsize; i++){
    if((i+1)%n == 0 && i != 0) {
    printf("%d\n",Elmnt[i]);
    }
    else
    printf("%d ",Elmnt[i]);
    }
    printf("\n");
    }
    
    
    ////////////////////////////////
    // read file //
    int Readfile(char *fname){
    FILE *f;
    int i;
    f = fopen(fname, "r");
    if (f == NULL) {
    fprintf(stderr, "file \"%s\" cannot open.\n", fname);
    return -1;
    }
    fscanf(f,"%d %d",&m, &n);
    Elmntsize = m*n;
    for (i=0; i < Elmntsize; i++){
    fscanf(f,"%d",&Elmnt[i]);
    }
    fclose(f);
    return 0;
    }
    
    
    ////////////////////////////////////////////////////////
    // Find the average number of threads //
    int avgCntRwTh(){
    if(m == t) return 1;
    if(t == 1) return m;
    return floor((float)m/t+0.5);
    }
    
    
    /////////////////////////////////////////////////////////////////////////
    // SHift of auxiliary tmp to new position(for right rotation) //
    void tmpShiftRR(int id, int iL){
    int i, preID;
    if(id == 0) preID = t-1;
    else preID = id-1;
    for (i=0; i<kAbs; i++){
    Elmnt[iL+i]= tmp[preID][kAbs-1-i];
    }
    }
    ----------------------------------------
    // right rotation function //
    ----------------------------------------
    void RotationR(int id, int iL, int iR){
    int i;
    for (i=0; i<kAbs; i++){
    tmp[id][i] = Elmnt[iR-i];
    }
    for (i=iR-kAbs; i>=iL; i--){
    Elmnt[i+kAbs] = Elmnt[i];
    }
    if(id == t-1) {
    tmpShift(id, iL);
    pthread_cond_signal(&cond[0]);
    }
    else {
    pthread_cond_wait(&cond[id], &mutex);
    tmpShiftRR(id, iL);
    pthread_cond_signal(&cond[id+1]);
    }
    }
    ---------------------------------------
    // Left rotation function //
    ---------------------------------------
    void RotationL(int id, int iL, int iR){
    int i;
    for (i=0; i<kAbs; i++){ tmp[id][i] = Elmnt[iL+i]; }
    for (i=iL; i<=iR; i++){ Elmnt[i] = Elmnt[i+kAbs]; }
    if(id == t-1) {
    tmpShiftRL(id, iR);
    }
    else {
    pthread_cond_wait(&cond[id], &mutex);
    tmpShiftRL(id, iR);
    }
    if(id != 0) pthread_cond_signal(&cond[id-1]);
    }
    
    
    --------------------
    // rotate //
    --------------------
    void *rotate(void *threadid){
    int id, cntR, pocR, konR, iL, iR;
    id = (int)threadid;
    printf("The working Thread is number: %d\n", id+1);
    cntR = avgCntRwTh(); // To find out how many rows to be worked on average amount
    pocR = (id)*cntR+1; // To provide rows where to begin rotation
    if(id == t-1) {
    cntR = m - (t-1)*cntR;
    sleep(1);
    } // For the Last thread of the remaining rows.
    konR = pocR+cntR -1;
    printf(" - This Threa is working with rows: %d-%d\n", pocR, konR);
    //
    iL = (pocR-1)*n; //First element of respective Thread
    iR = konR*n -1; // Last element
    //
    pthread_mutex_lock(&mutex);
    //
    if(k < 0) rotationL(id, iL, iR); // left
    else rotationR(id, iL, iR); // right
    //
    pthread_mutex_unlock(&mutex);
    //
    pthread_exit(NULL);
    return NULL;
    }
    
    
    
    
    ----------------------------------
    // main //
    -----------------------------------
    int main(int argc, char *argv[])
    {
    char File;
    int i, j, kN;
    pthread_t ths[MAX_THREADS];
    
    do {
    // The reading of data from the file
    do {
    printf("\nType the name of the file (pro ukonceni programu: -1): ");
    scanf("%s", &File);
    if(atoi(&File) == -1) exit(0);
    }
    while(ReadFile(&File) != 0 );
    printf("\nThe file was read:\n");
    Print();
    // The given number of Thread
    do {
    printf("Type total number of Threads(1-%d): ", m);
    scanf("%d", &t);
    if(t == -1) exit(0);
    }
    while(t < 1 || t > m);
    if(t>MAX_THREADS) t = MAX_THREADS;
    
    // The number of positions to be rotated
    printf("Enter number of positions to be rotated: ");
    scanf("%d", &k);
    kAbs = abs(k);
    if(kAbs > ElmntSize-1 && k >= 0) kAbs = kAbs %ElmntSize; // oriznuti kroku na velikost pole
    if(kAbs > ElmntSize && k < 0) kAbs = kAbs %ElmntSize;
    kN = kAbs /n; // pocet presahu na dalsi radek
    kAbs = kAbs %n; // total number of positions during the first pass
    // alokovani pomocneho 2d pole pro pomocne presuny
    tmp = (int **)malloc(t*sizeof(int*));
    for(i=0; i<t; i++)
    tmp[i]=(int *)malloc(n*sizeof(int));
    
    // Created Thread
    pthread_mutex_init(&mutex, NULL);
    for (j=0; j<=kN; j++){
    if (kAbs == 0) { kAbs = n; continue; }
    for(i=0; i<t; i++) {
    if(pthread_cond_init (&cond[i], NULL)) {
    printf("ERROR:During pthread_cond_init() - number %d\n)", i); exit(-1);
    }
    if(pthread_create(&ths[i], NULL, rotate, (void *) i)){
    printf("ERROR: During thread_create() - number %d\n)", i); exit(-1);
    }
    usleep(500000);
    }
    for(i=0; i<t; i++){
    pthread_join(ths[i], NULL);
    pthread_cond_destroy(&cond[i]);
    }
    kAbs = n;
    }
    pthread_mutex_destroy(&mutex);
    free(tmp);
    // Rotated array to be printed
    printf("\n\nRotated Array:\n");
    Print();
    printf("--- --- ---\n\n");
    sleep(2);
    } while (1);
    return 0;
    }

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Are you having a problem? If so, what is it?

    You're not going to get someone to look through a hundred lines of unindented code to help you look for something that might not exist.
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    5
    Quote Originally Posted by itsme86
    Are you having a problem? If so, what is it?

    You're not going to get someone to look through a hundred lines of unindented code to help you look for something that might not exist.
    My problem is how to interchange main diagonal and secondary diagonal with respect to threads....processing upper half part of the main and replacing it with upper one of secondary with respect to 2n threads and the second 1/4n threads process the following parts so on so forth...

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > My problem is how to interchange main diagonal and secondary diagonal with respect to threads
    So can we take it as read that you know how to do this without the complication of threads?

    If you can, why not post some practice thread code which just demonstrates passing messages between threads. Once you're sure of that bit, the rest is just detail.

    > scanf("%s", &File);
    On the other hand, perhaps you'd better stick to learning C first. Your first executable statement is a buffer overflow - this can't be a good sign.

    > free(tmp);
    Who did all the free(tmp[ i ]) calls?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Here's an updated version send to me via PM (I don't know how different it is, but at least it's indented):
    Quote Originally Posted by mozala
    Can somebody help me out?
    --------------------------------------
    Input: Square matrix A of nxn integers, where n is even.

    Rotate the elements of both diagonals in the clock direction.

    Input matrix 4x4

    1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 16

    Matrix 4x4 after rotation:

    13 2 3 1
    5 10 6 8
    9 11 7 12
    16 14 15 4

    Rotation is executed by 2n threads/processes.
    One quarter n/2 of threads/processes can
    read data from the upper half of the
    main diagonal (e.g. 4,7) and write them
    to the lower half of the secondary diagonal (e.g. 11,16).
    The second quarter of threads/processes can read data from
    the lower half of the secondary diagonal (e.g. 11,16) and
    write them to the lower half of the main diagonal (e.g. 10,13).
    The third quarter of threads/processes can read data from the
    lower half of the main diagonal (e.g. 10,13) and write them to
    the upper half of the secondary diagonal (e.g. 1,6). The last
    quarter of threads/processes can read data from the upper half of
    the secondary diagonal (e.g. 1,6) and write them to the upper
    half of the main diagonal (e.g. 4,7).

    Output: Input and output matrix.

    -------------------------------
    I've tried to begin the code so just pick out some mistakes and correct so that it can work..Thanks
    ----------------------------------
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <math.h>
    #define MAX_THREADS  100
    
    int Elmnt[10000];
    int **tmp;
    int m, n, Elmntsize, t, k, kAbs;
    pthread_mutex_t mutex;
    pthread_cond_t cond[MAX_THREADS];
    
    /////////////////////////////////////
    void Print () {
      int i;
      for(i=0; i<Elmntsize; i++){
        if((i+1)%n == 0 && i != 0) {
           printf("%d\n",Elmnt[i]); 
        }
        else
         printf("%d ",Elmnt[i]);  
      }
      printf("\n");  
    }
    
    
     ////////////////////////////////
    //       read file     //
    int  Readfile(char *fname){
      FILE *f;
      int i;
      f = fopen(fname, "r");
      if (f == NULL) {
        fprintf(stderr, "file \"%s\" cannot open.\n", fname);
        return -1;
      }
      fscanf(f,"%d %d",&m, &n);
      Elmntsize = m*n;
      for (i=0; i < Elmntsize; i++){
        fscanf(f,"%d",&Elmnt[i]);
      }   
      fclose(f);
      return 0;  
    }
    
    
     ////////////////////////////////////////////////////////
    //       Find the average number of threads  //
    int avgCntRwTh(){
      if(m == t) return 1;
      if(t == 1) return m;
      return floor((float)m/t+0.5);
    }
    
    
     /////////////////////////////////////////////////////////////////////////
    //   SHift of auxiliary tmp to new position(for right rotation)      //
    void tmpShiftRR(int id, int iL){
      int i, preID;  
      if(id == 0) preID = t-1;
        else preID = id-1;
      for (i=0; i<kAbs; i++){
        Elmnt[iL+i]= tmp[preID][kAbs-1-i];
      } 
    }
     ----------------------------------------
    //       right rotation function      //
    ----------------------------------------
    void RotationR(int id, int iL, int iR){
      int i;  
      for (i=0; i<kAbs; i++){
        tmp[id][i] = Elmnt[iR-i];
      }  
      for (i=iR-kAbs; i>=iL; i--){
    Elmnt[i+kAbs] = Elmnt[i];
      }  
      if(id == t-1) {
        tmpShift(id, iL);
        pthread_cond_signal(&cond[0]);    
      } 
      else { 
        pthread_cond_wait(&cond[id], &mutex); 
        tmpShiftRR(id, iL);
        pthread_cond_signal(&cond[id+1]);
      }  
    }
    ---------------------------------------
    //       Left rotation function      //
    ---------------------------------------
    void RotationL(int id, int iL, int iR){
      int i;  
      for (i=0; i<kAbs; i++){ tmp[id][i] = Elmnt[iL+i]; }  
      for (i=iL; i<=iR; i++){ Elmnt[i] = Elmnt[i+kAbs];  }  
      if(id == t-1) {
        tmpShiftRL(id, iR);  
      } 
      else { 
        pthread_cond_wait(&cond[id], &mutex); 
        tmpShiftRL(id, iR);
      }  
      if(id != 0) pthread_cond_signal(&cond[id-1]);
    }
    
    
     --------------------
    //  rotate      //  
    --------------------
    void *rotate(void *threadid){
      int id, cntR, pocR, konR, iL, iR;
      id = (int)threadid;
      printf("The working Thread is number: %d\n", id+1);
      cntR = avgCntRwTh();                         // To find out how many rows to be worked on average amount
      pocR = (id)*cntR+1;                          // To provide rows where to begin rotation
      if(id == t-1) {
        cntR = m - (t-1)*cntR;
        sleep(1);
      }     // For the Last thread of the remaining rows.
      konR = pocR+cntR -1;
      printf("     - This Threa is working with rows: %d-%d\n", pocR, konR);
      //
      iL = (pocR-1)*n;           //First element of respective Thread
      iR = konR*n -1;            // Last element 
      //
      pthread_mutex_lock(&mutex);  
      //
      if(k < 0) rotationL(id, iL, iR);              // left
        else    rotationR(id, iL, iR);              // right
      // 
      pthread_mutex_unlock(&mutex); 
      //
      pthread_exit(NULL);  
      return NULL;  
    }  
    
    
    
        
    ----------------------------------
    //             main            //
    -----------------------------------
    int main(int argc, char *argv[])
    {
      char File;
      int i, j, kN;
      pthread_t ths[MAX_THREADS];
     
      do {     
           // The reading of data from the file
        do {
          printf("\nType the name of the file (pro ukonceni programu: -1): ");
          scanf("%s", &File);
          if(atoi(&File) == -1) exit(0);
        } 
        while(ReadFile(&File) != 0 );
        printf("\nThe file was read:\n");
        Print();
            // The given number of Thread  
        do {
          printf("Type total number of Threads(1-%d): ", m);
          scanf("%d", &t);
          if(t == -1) exit(0);
        } 
        while(t < 1 || t > m); 
        if(t>MAX_THREADS) t = MAX_THREADS;
       
           // The number of positions to be rotated  
        printf("Enter number of positions to be rotated: ");
        scanf("%d", &k);
        kAbs = abs(k);
        if(kAbs > ElmntSize-1 && k >= 0) kAbs = kAbs %ElmntSize;      // oriznuti kroku na velikost pole
        if(kAbs > ElmntSize && k < 0) kAbs = kAbs %ElmntSize;   
        kN = kAbs /n;                                                 // pocet presahu na dalsi radek
        kAbs = kAbs %n;                                               // total number of positions during the first pass                                          
          // alokovani pomocneho 2d pole pro pomocne presuny   
        tmp = (int **)malloc(t*sizeof(int*));  
        for(i=0; i<t; i++)               
          tmp[i]=(int *)malloc(n*sizeof(int));
    
          //  Created Thread
        pthread_mutex_init(&mutex, NULL);
        for (j=0; j<=kN; j++){
          if (kAbs == 0) { kAbs = n; continue; }
          for(i=0; i<t; i++) {
            if(pthread_cond_init (&cond[i], NULL)) {
              printf("ERROR:During pthread_cond_init() - number %d\n)", i); exit(-1); 
            }
            if(pthread_create(&ths[i], NULL, rotate, (void *) i)){
              printf("ERROR: During thread_create() - number %d\n)", i); exit(-1); 
            }        
            usleep(500000);
          }    
          for(i=0; i<t; i++){ 
            pthread_join(ths[i], NULL); 
            pthread_cond_destroy(&cond[i]);
          }
          kAbs = n;
        }  
        pthread_mutex_destroy(&mutex);
        free(tmp);
            // Rotated array to be printed
        printf("\n\nRotated Array:\n");
        Print();
        printf("--- --- ---\n\n");
        sleep(2);
      } while (1);
      return 0;
    }
    Quote Originally Posted by Salem
    > free(tmp);
    Who did all the free(tmp[ i ]) calls?
    This still isn't fixed.

    > scanf("%s", &File);
    On the other hand, perhaps you'd better stick to learning C first. Your first executable statement is a buffer overflow - this can't be a good sign.
    Neither is this. Maybe I can clarify.
    Code:
      char File;
      int i, j, kN;
      pthread_t ths[MAX_THREADS];
     
      do {     
           // The reading of data from the file
        do {
          printf("\nType the name of the file (pro ukonceni programu: -1): ");
          scanf("%s", &File);
    scanf() is expecting a string to be passed to it (%s), but you're passing the address of a single character. You should use an array, like this
    Code:
    char File[FILENAME_MAX];
    Better yet, use fgets() instead of scanf():
    Code:
    #include <string.h>
    char File[FILENAME_MAX], *p;
    fgets(File, sizeof(File), stdin);
    if((p = strchr(File, '\n'))) *p = 0;[/code]
    fgets() doesn't overflow you buffer (if you pass it the right size, sizeof(File) or FILENAME_MAX or however big it is) and it lets you read spaces. (You have to remove the newline from the string read by fgets() unless you want it there.)

    So, entering "C:\My Documents\hello world.txt" will cause scanf() to read in "C:\My" (and leave the rest in the input stream, which will cause problems later because you don't check the return value of your scanf("%d")s), while fgets will read "C:\My Documents\hello world.txt\n". (The if(strchr()) part removes the newline, so it becomes "C:\My Documents\hello world.txt", which is what you want.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 22
    Last Post: 12-14-2012, 11:00 AM
  2. Threads and Process
    By mozala in forum C Programming
    Replies: 1
    Last Post: 05-17-2006, 12:56 AM
  3. Threads terminate when parent process does?
    By BigDaddyDrew in forum Windows Programming
    Replies: 1
    Last Post: 04-21-2004, 04:32 PM
  4. Child Process & Parent Process Data :: Win32
    By kuphryn in forum Windows Programming
    Replies: 5
    Last Post: 09-11-2002, 12:19 PM