文件名未传入pthread_create

时间:2017-11-11 01:22:30

标签: c multithreading pthreads pthread-join

这是程序中的两个问题 首先,当我在main函数中取消注释pthread_join()时,会出现seg错误,否则程序将运行... 其次,输出文件将缺少存储在上次读取文件的全局变量字中的每个单词的第一个字母。因此,例如,有两个文件:

一个人有一句话“abc abc abc abc abc abc abc abc”。

第二个词有“def def”

如果我在调用a.out时为第二个参数输入5,则输出文件中的输出将为     ABC     ABC     ABC     ABC     ABC     公元前     公元前     公元前     高清     高清 这也是一个我无法弄清楚原因的事情。

/* main.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <ctype.h>
#include <pthread.h>
#include "hw3.h"
int index_;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

typedef struct files
{
    char *inputfile;
    FILE * outputfile;

} files;

void * readFile( void *arg ){

    files *info = (files *)arg;
    char fileName[80];
    strncat(fileName, (info->inputfile), 79);
    fileName[80] = '\0';
    FILE *outputfd = info->outputfile;
    FILE* fd;
    fd = fopen(fileName, "r");
    if ( fd  == NULL) {
      fprintf(stderr, "ERROR:<open() failed>\n");
    }

    printf("TID %d: Opened \"%s\"\n", (unsigned int)pthread_self(), fileName);
    fflush(stdout);
    int rc;
    char ch[1] = {0};
    char word[80] = {0};
    ch[0] = fgetc(fd);
    pthread_mutex_lock(&mutex);
    while( ch[0] != EOF){
      if( isalnum(ch[0]) ){
      //  char str = ch[0];
      strncat(word, ch, 1);
      }
      else{//it's a word
        if( strlen( word ) >= 2 ){

          words[index_] = word;
          printf("TID %d: Stored \"%s\" in shared buffer at index [%d]\n",(unsigned int)pthread_self(), word, index_ );
          if( index_+ 1 == maxwords ){
            index_ = 0;
            printf("MAIN: Buffer is full; writing %d words to output file\n", maxwords);
            for( unsigned int i = 0; i<maxwords; i++ ){
              rc = fwrite(  words[i], 1, sizeof(words[i]), outputfd  );
              fwrite(  "\n", 1, sizeof("\n"), outputfd );
              if( rc == -1 ){
                fprintf(stderr, "ERRPR:<write() failed>\n");
                //return EXIT_FAILURE;
              }
            }
          }
          else{
            index_ ++;
          }
        }
        for(int i = 0; i< strlen(word); i++){
          word[i] = '\0';
        }
      }
    ch[0] = fgetc(fd);
    }
    pthread_mutex_unlock(&mutex);
    printf("TID %d: Closed \"%s\"; and exiting\n", (unsigned int)pthread_self(), fileName );
    fclose(fd);
    pthread_exit( NULL );
}

int main( int argc, char * argv[] ){

  if(argc != 4){
  fprintf(stderr, "ERROR: Invalid arguments\nUSAGE: ./a.out <input-directory> <buffer-size> <output-file>\n");
    return EXIT_FAILURE;
  }
  //dynamically allocated words buffer with argument 2
  maxwords = atoi(argv[2]);
  words = (char**)calloc(maxwords, sizeof(char*) );

  if ( words == NULL)
  {
    fprintf( stderr, "ERROR:<word calloc() failed\n>" );
    return EXIT_FAILURE;
  }

  printf("MAIN: Dynamically allocated memory to store %d words\n", maxwords);
  fflush(stdout);

  //open/create output file of the third argument
  FILE* outputfd = fopen (argv[3], "w");
  if ( outputfd == NULL )
  {
    perror( "open() failed" );
    return EXIT_FAILURE;
  }
  DIR * dir = opendir( argv[1] );

  if(dir == NULL){
    perror("ERRPR:<opendir() failed>");
    return EXIT_FAILURE;
  }
  chdir(argv[1]);

  printf("MAIN: Opened \"%s\" directory\n", argv[1]);
  fflush(stdout);

  pthread_t tid[10];
  index_ = 0;
  int i = 0;//files index

  struct dirent * file;
  //files allfiles[20];
  char fileName[80];
  int rc;

  //-----------------------------------------------------------------------
  // while loop reads all files in the directory
  while ( ( file = readdir( dir ) ) != NULL )
  {
    struct stat buf;
    rc = lstat( file->d_name, &buf );  /* e.g., "xyz.txt" */
    /* ==> "assignments/xyz.txt" */

    if ( rc == -1 ){
      fprintf(stderr, "ERRPR:<lstat() failed>\n");
      return EXIT_FAILURE;
    }

    if ( S_ISREG( buf.st_mode ) )
    {
    //      printf( " -- regular file\n" );
   //      fflush(stdout);
      strncpy(fileName, file->d_name, 79);

      files info;
      info.inputfile = fileName;
      info.outputfile = outputfd;
      //printf("%d",i);
      printf("MAIN: Created child thread for \"%s\"\n",fileName);
      rc = pthread_create( &tid[i], NULL, readFile,(void *)&info );
      sleep(1);
      i++
    }
    else if ( S_ISDIR( buf.st_mode ) )
    {
    //      printf( " -- directory\n" );
    //      fflush(stdout);
    }
    else
    {
   //      printf( " -- other file\n" );
   //      fflush(stdout);
    }
  }

  closedir(dir);
  printf("MAIN: Closed \"%s\" directory\n", argv[1]);
  fflush(stdout);
  printf("MAIN: Created \"%s\" output file\n",argv[3]);
  fflush(stdout);
  //-----------------------------------------------------------------------

  for( int j = 0; j<i; j++){

      printf( "MAIN: Joined child thread: %u\n", (unsigned int)tid[j] );
      pthread_join(tid[i], NULL);
  }


  for( unsigned int i = 0; i<index_; i++ ){
    int rc = fwrite( words[i], 1, sizeof(words[i]), outputfd );
    if( rc == -1 ){
      fprintf(stderr, "ERRPR:<write() failed>\n");
      return EXIT_FAILURE;
    }
  }
  printf( "MAIN: All threads are done; writing %d words to output file\n", index_);
  fflush(stdout);

  free( words );
  fclose( outputfd );
  return EXIT_SUCCESS;
}

这是整个程序,并且有一个头文件只是两个全局变量

char ** words = NULL;

/* global/shared integer specifying the size */
/*  of the words array (from argv[2])        */
int maxwords;

感谢大家的帮助!

2 个答案:

答案 0 :(得分:0)

每个线程需要单独的info个对象。现在,所有线程都获得相同的info对象,您可以在创建线程之间进行更改,因此,对于大多数线程,当他们有机会查看文件名时应该处理,它已被改变。

分段错误是由您未向我们展示的代码引起的,因此除了建议您应用valgrind之外,我无法帮助您。

答案 1 :(得分:0)

以下是另外两个错误:

char fileName[80];
strncat(fileName, (info->inputfile), 79);

您只能连接到字符串,而不是可能包含或不包含有效字符串的单位化字符数组。

char ch[1] = {0};
char word[80] = {0};
ch[0] = fgetc(fd);
pthread_mutex_lock(&mutex);
while( ch[0] != EOF){

fgets函数返回一个在文件末尾为EOF的整数,否则返回字符值。您将其转换为char,然后将charEOF进行比较。但这没有任何意义,因为EOF是表示文件结尾的整数值。一旦转换为字符,它就是一个可以从文件中读取的有效字符,因为该文件可以包含任何字符和文件结尾#34;不是一个角色。