Wielowątkowe zliczanie znaków z pliku

0

Witam, mam za zadanie napisać program który zliczy ilość znaków (przecinki/kropki) w pliku.

 #include <windows.h>
#include <process.h>
#include <iostream>
#include <fstream>
using namespace std;
unsigned _stdcall FunkcjaWatku(void * arg)
{
fstream plik;
char c;
plik.open("plik.txt", ios::in );
    if(plik.good() == true)
    {
ifstream in("plik.txt");
int b=0;
{
while (!plik.eof() )
   {
       c=plik.get();
   if (c==',') b++;
   }
cout<<b;
plik.close();
    }
_endthreadex(0);
return 0;
}
};
int main()
{
unsigned IdentWatku[1];
HANDLE hWatki [1];
char w1[] = "Pierwszy watek";
hWatki[0] = (HANDLE)_beginthreadex (NULL, 0,&FunkcjaWatku, (void*)w1, 0, &IdentWatku[0]);
WaitForMultipleObjects(1, hWatki, TRUE, INFINITE);
CloseHandle (hWatki [0]);
return 0;
}

Program w tej postaci działa ale nie ma sensu. Chciałem utworzyć trzy wątki który każdy szukałby innego znaku. I tu się pojawia problem, podejrzewam że źle przypisuje zmienną znaku(char znak) do wskaźnika (arg). Program wypluwa
Przechwytywanie.PNG
mimo tego że w tekście znajduje się jeden przecinek

 #include <windows.h>
#include <process.h>
#include <iostream>
#include <fstream>
using namespace std;
unsigned _stdcall FunkcjaWatku(void * arg)
{
fstream plik;
char c;
int b=0;
char * znak = (char *) arg;
plik.open("plik.txt", ios::in );
    if(plik.good() == true)
    {
ifstream in("plik.txt");
{
while (!plik.eof() )
   {
       c=plik.get();
   if (c==znak) b++;
   }
cout<<"Poszukiwany znak to >>"<<znak<<"<< w tekscie takich znakow znajduje sie : "<<b<<endl;
plik.close();
    }
_endthreadex(0);
return 0;
}
};
int main()
{
unsigned IdentWatku[3];
HANDLE hWatki [3];
char w1 = ',';
//char w2[] = ".";
//char w3[] = " ";
hWatki[0] = (HANDLE)_beginthreadex (NULL, 0,&FunkcjaWatku, &w1, 0, &IdentWatku[0]);
//hWatki[1] = (HANDLE)_beginthreadex (NULL, 0,&FunkcjaWatku, &w2, 0, &IdentWatku[1]);
//hWatki[2] = (HANDLE)_beginthreadex (NULL, 0,&FunkcjaWatku, &w3, 0, &IdentWatku[2]);
WaitForMultipleObjects(1, hWatki, TRUE, INFINITE);
CloseHandle (hWatki [0]);
//CloseHandle (hWatki [1]);
//CloseHandle (hWatki [3]);
return 0;
}
0

1.FORMATOWANIE KODU.
2.Gdzie tam masz niby char znak?

0

Coś pokręciłeś z zadaniem. Przy zliczaniu znaków z pliku "wąskim gardłem" jest samo czytanie, więc szukanie każdym wątkiem innego znaku mija się z celem. Co innego kiedy każdy z wątków działa na innym fragmencie tego samego pliku a po zakończeniu dane są sumowane. Poza tym C++ dorobiło się własnych wątków czemu to nie wykorzystać?

#include <iostream>
#include <fstream>
#include <thread>
using namespace std;

int main()
  {
   char find[]={'.',',',';'};
   const unsigned findcount=sizeof(find)/sizeof(*find);
   unsigned long long counts[findcount]={0};
   thread th[findcount];
   for(unsigned i=0;i<findcount;++i)
     {
      th[i]=thread
        (
         [i,find,&counts]
           {
            ifstream fs("ThreadTest.cpp");
            int ch;
            while((ch=fs.get())!=EOF) if(ch==find[i]) ++counts[i];
           }
        );
     }
   for(unsigned i=0;i<findcount;++i)
     {
      th[i].join();
      cout<<"znak "<<find[i]<<" wystepuje "<<counts[i]<<" razy."<<endl;
     }
   return 0;
  }

Ale jak już mówiłem wyżej powinno to wyglądać mniej więcej tak:

#include <iostream>
#include <fstream>
#include <thread>
using namespace std;

int main()
  {
   const unsigned threadcount=4;
   char find[]={'.',',',';'};
   const unsigned findcount=sizeof(find)/sizeof(*find);
   unsigned long long counts[threadcount][findcount]={{0}};
   ifstream fs("ThreadTest.cpp",ios::in|ios::binary);
   fs.seekg(0,ios::end);
   unsigned long long 
      size=fs.tellg(),
      part=size/threadcount,
      read=size-part*(threadcount-1),
      start=0
     ;
   fs.close();
   thread th[threadcount];
   for(unsigned t=0;t<threadcount;++t)
     {
      th[t]=thread
        (
         [t,find,findcount,start,read,&counts]
           {
            ifstream fs("ThreadTest.cpp");
            fs.seekg(start,ios::beg);
            for(unsigned long long r=0;r<read;++r)
              {
               char ch=fs.get();
               for(unsigned i=0;i<findcount;++i) if(ch==find[i]) ++counts[t][i];
              }
           }
        );
      start+=read;
      read=part;
     }
   for(unsigned t=0;t<threadcount;++t) th[t].join();
   for(unsigned i=0;i<findcount;++i)
     {
      unsigned long long count=0;
      for(unsigned t=0;t<threadcount;++t) count+=counts[t][i];
      cout<<"znak "<<find[i]<<" wystepuje "<<count<<" razy."<<endl;
     }      
   return 0;
  }
0

Prawdę powiedziawszy ten program nie miał być demonem prędkości

char * znak = (char *) arg; 

Ta deklaracja w wątku jest poprawna?
_13th_Dragon dziękuje za program, jak tylko wrócę z pracy przeanalizuję go bo nie potrafię w ten sposób jak Ty korzystać z wątków(wychodzi na to że wcale nie potrafię z nich korzystać :P).
edit Jeżeli ktoś na przyszłość by potrzebował

 
#include <windows.h>
#include <process.h>
#include <iostream>
#include <fstream>
using namespace std;
CRITICAL_SECTION sekcja_krytyczna;
unsigned _stdcall FunkcjaWatku(void * arg)
{
fstream plik;
char c;
int b=0;
char * znak = (char *) arg;
plik.open("plik.txt", ios::in );
if(plik.good() == true)
    {
    ifstream in("plik.txt");
        {
        while (!plik.eof() )
            {
            c=plik.get();
            if (c==*znak) b++;
            }
        EnterCriticalSection (& sekcja_krytyczna);
        if (*znak==',') cout<<" przecinek, wystapil on "<<b<<" razy |"<<endl;
        if (*znak==' ') cout<<" spacja, wystapila ona "<<b<<" razy |"<<endl;
        if (*znak=='.') cout<<" kropka, wystapila ona "<<b<<" razy |"<<endl;
        LeaveCriticalSection (& sekcja_krytyczna);
        plik.close();
        }
    _endthreadex(0);
    return b;
    }
};
int main()
{
unsigned IdentWatku[3];
HANDLE hWatki [3];
char w1=',';
char w2='.';
char w3=' ';
InitializeCriticalSection (& sekcja_krytyczna);
hWatki[0] = (HANDLE)_beginthreadex (NULL, 0,&FunkcjaWatku, &w1, 0, &IdentWatku[0]);
hWatki[1] = (HANDLE)_beginthreadex (NULL, 0,&FunkcjaWatku, &w2, 0, &IdentWatku[1]);
hWatki[2] = (HANDLE)_beginthreadex (NULL, 0,&FunkcjaWatku, &w3, 0, &IdentWatku[2]);
WaitForMultipleObjects(3, hWatki, TRUE, INFINITE);
CloseHandle (hWatki [0]);
CloseHandle (hWatki [1]);
CloseHandle (hWatki [2]);
DeleteCriticalSection (&sekcja_krytyczna);
return 0;
}

Takie coś musiałem zrobić

1 użytkowników online, w tym zalogowanych: 0, gości: 1