C程序在GDB中工作但不正常

时间:2017-10-17 20:35:34

标签: c multithreading race-condition

每当我正常运行下面的代码时,它会立即退出。但是,当我在GDB中运行它时,它正常运行,我得到了所需的输出。在添加线程之前,程序工作正常,所以我确定错误就是这样。我想我的代码中可能存在可能导致问题的竞争条件,但我并不完全确定。有关为什么会发生这种情况的任何建议吗?代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>

#define NUMTHRDS 4
pthread_t callThd[NUMTHRDS];
pthread_mutex_t mutexsum;


char* stradd(const char* a, const char* b){
   size_t len = strlen(a) + strlen(b);
   char *ret = (char*)malloc(len * sizeof(char) + 1);
   *ret = '\0';
   return strcat(strcat(ret, a) ,b);
}

void lower_string(char *string)
{
   while(*string)
   {
      if ( *string >= 'A' && *string <= 'Z' )
      {
         *string = *string + 32;
      }
      string++;
   }
}

void *removeNoise(char *arra1[14284][128], char *noiseList1[15][128]) {
   int i, j;
   /* mark for removal */
   for( i=0; arra1[i][0] != 0x00; i++ ) {
       for( j=0; noiseList1[j][0] != 0x00; j++ ) {
          if(strcmp(arra1[i], noiseList1[j]) == 0) {
            pthread_mutex_lock (&mutexsum);
            arra1[i][0]=0x1A; /* ASCII ctrl char for substitute - chosen 
                                arbitrarily */
            pthread_mutex_unlock (&mutexsum);
          }
       }
   }

   /* one pass to remove */
   for( i=0, j=0; arra1[i][0] != 0x00; i++,j++ ) {
     while( arra1[i][0] == 0x1A )
        i++;

     if(i!=j) {
        pthread_mutex_lock (&mutexsum);
        strcpy(arra1[j],arra1[i]);
        pthread_mutex_unlock (&mutexsum);
     }
   }
   pthread_mutex_lock (&mutexsum);
   strcpy(arra1[j],arra1[i]);
   pthread_mutex_unlock (&mutexsum);
   pthread_exit((void*) 0);
 }

 void *substitution(char *arra1[14284][128], char *originalList[10][128], 
 char *replacementList[10][128], int size) {
    int i, j;
    for(i = 0; i < size; i++) {
        for(j = 0; j < 10; j++) {
            if(strcmp(arra1[i], originalList[j]) == 0) {
                pthread_mutex_lock (&mutexsum);
                strcpy(arra1[i], replacementList[j]);
                pthread_mutex_unlock (&mutexsum);
            }
        }
    }

    pthread_exit((void*) 0);
 }

 void *findFreq(char *arra1[14284][128], int freq[14284], int size) {
     int i, j, count;
     for(i=0; i<size; i++)
     {
        /* Initially initialize frequencies to -1 */
        freq[i] = -1;
     }

     for(i=0; i<size; i++)
     {
        count = 1;
        for(j=i+1; j<size; j++)
        {
            /* If duplicate element is found */
            if(strcmp(arra1[i], arra1[j]) == 0)
            {
                count++;
                pthread_mutex_lock (&mutexsum);
                /* Make sure not to count frequency of same element again */
                freq[j] = 0;
                pthread_mutex_unlock (&mutexsum);

            }
        }

        /* If frequency of current element is not counted */
        if(freq[i] != 0)
        {
            pthread_mutex_lock (&mutexsum);
            freq[i] = count;
            pthread_mutex_unlock (&mutexsum);
        }
    }

    pthread_exit((void*) 0);

    /*printf("\nFrequency of all elements of array : \n");
    for(i=0; i<size; i++)
    {
       if(freq[i] != 0)
       {
           printf("%s occurs %d times\n", arra1[i], freq[i]);
       }
    }*/
 }

 void *findCommon(char *arra1[14284][128], int freq[14284], int size) {
    int i, j;
    int common = 13;
    int max, temp;
    char tempArr[128][128];

    for (i = 0; i < common; i++)
    {
        pthread_mutex_lock (&mutexsum);
        max = i;
        // Find next max index
        for (j = i+1; j < size; j++)
        {
           if (freq[j] > freq[max])  {
               max = j;
           }
        }
        // Swap numbers in input array
        tempArr[0][0] = arra1[i][0];
        arra1[i][0] = arra1[max][0];
        arra1[max][0] = tempArr[0][0];
        // Swap indexes in tracking array
        temp = freq[i];
        freq[i] = freq[max];
        freq[max] = temp;
        pthread_mutex_unlock (&mutexsum);
    }

    for (i = 0; i < common; i++) {
       printf("%d -> %s\n", freq[i], arra1[i]);
    }

    pthread_exit((void*) 0);
 }

 /* Read in all files from a folder */
 int main(int argc, char **argv)
 {
     char *fileArray[78];
     int i, j;
     DIR *d;
     struct dirent *dir;
     char arra[128][128];
     char *arra1[14284][128];
     char line[1024];
     char line1[1024];
     char line2[1024];
     char noiseList[128][128];
     char *noiseList1[15][128];
     char conceptList[128][128];
     char *conceptList1[20][128];
     char *originalList[10][128];
     char *replacementList[10][128];
     char *token;
     char *token1;
     char *path = "./alerts2013/2013/";
     char *path1 = "./Noise_and_Concepts/";
     char *fileName;
     char *fileName1;
     char *fileName2;
     int freq[14284];
     char seps[] = " ,\t\n";
     FILE *myfile;
     FILE *noise;
     FILE *concept;
     int size = 0;
     int replaceSize = 0;
     d = opendir("./alerts2013/2013");
     fileName1 = stradd(path1, "noise.txt");
     fileName2 = stradd(path1, "concepts.txt");
     //printf("%s\n", fileName1); 
     noise = fopen(fileName1, "r");
     if (noise == 0)
     {
         printf("can not open file \n");
         exit(1);
     }
     int a, b;
     for(a = 0; a < 128; a++) {
         line[a] = '\0';
         line2[a] = '\0';
     }

     for(a = 0; a < 128; a++) {
         for(b = 0; b < 128; b++) {
             noiseList[a][b] = '\0';
             noiseList1[a][b] = '\0';
             arra[a][b] = '\0';
             arra1[a][b] = '\0';
             conceptList[a][b] = '\0';
             conceptList1[a][b] = '\0';
             originalList[a][b] = '\0';
             replacementList[a][b] = '\0';
         }
     }
     i = 0;
     j = 0;
     int k = 0;
     int l = 0;
     int m = 0;
     int n = 0;
     int q = 0;
     int r = 0;
     while(fgets(line, sizeof(line), noise) != NULL) {
         strcpy(noiseList[k], line);
         //printf("%s", noiseList[k]);
         token = strtok(noiseList[k], seps);
         while(token != NULL )
         {
            /* While there are tokens in "string" */
            //printf("%s\n", token);
            //printf("array ----> %s\n", token);

            lower_string(token);
            strcpy(noiseList1[n], token);
            n++;
            /* Get next token: */
            token = strtok( NULL, seps );

        }
        k++;
     }

     concept = fopen(fileName2, "r");
     if (concept == 0)
     {
         printf("can not open file \n");
         exit(1);
     }

     while(fgets(line2, sizeof(line2), concept) != NULL) {
         strcpy(conceptList[q], line2);
         //printf("%s", noiseList[q]);
         token = strtok(conceptList[q], seps);
         while(token != NULL )
         {
            /* While there are tokens in "string" */
            //printf("%s\n", token);
            //printf("array ----> %s\n", token);

            lower_string(token);
            strcpy(conceptList1[r], token);
            r++;
            /* Get next token: */
            token = strtok( NULL, seps );

        }
        q++;
     }

     for(i = 0; i < 20; i++) {
         if(i == 0) {
             strcpy(originalList[0], conceptList1[0]);
         }

         if(i % 2 == 0) {
             strcpy(originalList[i/2], conceptList1[i]);
         }

         else {
             strcpy(replacementList[replaceSize], conceptList1[i]);
             replaceSize++;
         }
     }

     if (d)
     {
         while ((dir = readdir(d)) != NULL)
         {
             fileArray[i] = dir->d_name;
             //printf("%s\n", fileArray[i]);
             fileName = stradd(path, dir->d_name);
             //printf("%s\n", fileName);
             free(fileName);
             myfile = fopen(fileName,"r");
             if (myfile == 0)
             {
                 printf("can not open file \n");
                 exit(1);
             }

             for(i = 0; i < 128; i++) {
                 line1[i] = '\0';
             }

             if(myfile != NULL) {
                 while(fgets(line1, sizeof(line1), myfile) != NULL) {
                     strcpy(arra[l], line1);
                     //printf("Tokens:\n" );
                     /* Establish string and get the first token: */
                     token = strtok(arra[l], seps);
                     while(token != NULL )
                     {
                         /* While there are tokens in "string" */
                         //printf("%s\n", token);
                         //printf("array ----> %s\n", token);

                         lower_string(token);
                         strcpy(arra1[m], token);
                         //printf("Arra1: %s\n", arra1[m]);
                         size++;
                         m++;
                         /* Get next token: */
                         token = strtok( NULL, seps );

                     }


                     //printf("array ----> %s ", &arra[i]);
                     i++;

                 }
             }

             fclose(myfile);


             i++;
         }

         closedir(d);
     }

     pthread_attr_t attr;
     void *status;
     pthread_mutex_init(&mutexsum, NULL);
     /* Create threads to perform the dotproduct  */
     pthread_attr_init(&attr);
     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

     for(i=0;i<NUMTHRDS;i++)
     {
         /* Each thread works on a different set of data.
         * The offset is specified by 'i'. The size of
         * the data for each thread is indicated by VECLEN.
         */
         pthread_create(&callThd[i], &attr, removeNoise(arra1, noiseList1),        
         (void *)i); 
     }

     pthread_attr_destroy(&attr);
     /* Wait on the other threads */

     for(i=0;i<NUMTHRDS;i++) {
         pthread_join(callThd[i], &status);
     }

     for(i=0;i<NUMTHRDS;i++)
     {
         /* Each thread works on a different set of data.
         * The offset is specified by 'i'. The size of
         * the data for each thread is indicated by VECLEN.
         */
         pthread_create(&callThd[i], &attr, substitution(arra1, 
         originalList, replacementList, size), (void *)i); 
}

     pthread_attr_destroy(&attr);
     /* Wait on the other threads */

     for(i=0;i<NUMTHRDS;i++) {
         pthread_join(callThd[i], &status);
     }

     for(i=0;i<NUMTHRDS;i++)
     {
         /* Each thread works on a different set of data.
         * The offset is specified by 'i'. The size of
         * the data for each thread is indicated by VECLEN.
         */
         pthread_create(&callThd[i], &attr, findFreq(arra1, freq, size), 
         (void *)i); 
     }

     pthread_attr_destroy(&attr);
     /* Wait on the other threads */

     for(i=0;i<NUMTHRDS;i++) {
         pthread_join(callThd[i], &status);
     }

     for(i=0;i<NUMTHRDS;i++)
     {
         /* Each thread works on a different set of data.
         * The offset is specified by 'i'. The size of
         * the data for each thread is indicated by VECLEN.
         */
         pthread_create(&callThd[i], &attr, findCommon(arra1, freq, size), 
         (void *)i); 
}

     pthread_attr_destroy(&attr);
     /* Wait on the other threads */

     for(i=0;i<NUMTHRDS;i++) {
         pthread_join(callThd[i], &status);
     }

     /*int p;
     int w;
     printf("%d\n", size);
     for(p = 0; p < 10; p++) {
         printf("%s\n", replacementList[p]);
     }
     for(w = 0; w < size; w++) {
         printf("Arr1 (final): %s\n", arra1[w]);
     }*/

     FILE * Output;
     Output = fopen("data.txt", "w");
     for(i = 2; i < 12; i++) {
         fprintf(Output, "%d -> %s", freq[i], arra1[i]);
         fprintf(Output, " ");
     }

     fclose(Output);
     fclose(noise);
     fclose(concept);
     pthread_mutex_destroy(&mutexsum);
     pthread_exit(NULL);
     return(0);
   }

1 个答案:

答案 0 :(得分:3)

如果查看pthread_create的文档,它会说SELECT JSONB_SET( '{"k1": {"value": "v1"}}', '{k2}', '{"value": "v2"}', TRUE ); jsonb_set ------------------------------------------------ {"k1": {"value": "v1"}, "k2": {"value": "v2"}} (1 row) 。这意味着它需要一个指向函数的指针,该函数需要void *(*start_routine) (void *)并返回void *。您的代码中没有任何此类功能。那么如何将指向这样一个函数的指针传递给void *

你有这个:

pthread_create

但是这会调用 pthread_create(&callThd[i], &attr, removeNoise(arra1, noiseList1), (void *)i); 并将返回的值传递给removeNoise。您希望新线程调用pthread_create,但此代码本身会调用removeNoise。那不对。

创建一个带removeNoise的函数并返回void *并将指向该函数的指针传递给void *,正如文档所说的那样。