Wielowątkowość - czy da się obejść Sleep-a? Organizacja kodu.

0

Witam, mam "drobny" problem. Otóż chcę napisać program, który będzie mi wczytywał dane z pliku wielowątkowo tzn. w taki sposób, że główny wątek będzie "ładował" dane z pliku do wolnego bufora a reszta wątków będzie konwertować te dane do odpowiednich obiektów.
Póki co zrobiłem część odpowiadającą za wielowątkowe liczenie wierszy w pliku (by wiedzieć jak dużą tablicę obiektów mam stworzyć).
Mam niestety mały problem, który udało mi się zlokalizować, ale mam problem ze znalezieniem rozwiązania.

Otóż utworzone wątki przestają działać, gdy zmienna break_threads przyjmie wartość true. Do tego czasu wszystkie wątki chodzą w pętli while. Gdy główny wątek załaduje dane do odpowiedniego bufora i znajdzie wolny wątek to przekazuje mu dane i ustawia zmienną wait_for_data[i] = 0; - to powoduje, że wątek zaczyna wykonywać obliczenia.
Problem jest taki, że czasami jakiś wątek nie wykonuje obliczeń (chodzi prawdopodobnie o jeden z ostatnich buforów). Chodzi prawdopodobnie o to, że gdy następuje zmiana wartości zmiennej wait_for_data[i] to wątek od razu ładuje kolejny bufor. Natomiast wewnątrz wątku prawdopodobnie, od czasu do czasu, są pewne zastoje i zanim pętla while wewnątrz wątku sprawdzi zmienną wait_for_data to główny wątek zmienia wartość break_threads na true i wątek nie wykonuje ostatnich obliczeń. Dzieje się to sporadycznie (głównie przy małych buforach), ale jednak... I chcę tego uniknąć!
Jednym z rozwiązań tego problemu jest umieszczenie Sleep(100) przed przypisaniem zmiennej break_threads wartości true ale to rozwiązanie średnio mnie zadowala, bo z jednej strony wydłuża pracę funkcji a z drugiej strony nie gwarantuje 100% pozbycia się problemu.

Dlatego, jeśli jest taka możliwość, bardzo proszę o wskazanie jakiegoś sensownego rozwiązania.

Poniżej umieszczam kod opisywanych funkcji.

//nvm
2

Poczytaj o eventloopach, Twój problem brzmi jak idealne zastosowanie.

4
  1. Nie dziel zadania ma zbyt małe porcje - to powoduje że więcej tracisz na synchronizacji niż zyskujesz na równoległych obliczeniach.
  2. Nie próbuj odczytywać pliku wielowątkowo - to mija się z celem, ponieważ system i tak odczytuje dysk jednowątkowo na dodatek bardzo wolno.
  3. "... wielowątkowe liczenie wierszy w pliku (by wiedzieć jak dużą tablicę obiektów mam stworzyć)." - samo liczenie wierszy w pliku aby później czytać go raz jeszcze to już wielki bubel projektowy. Czytaj i od razu dodawaj do wektora, listy, drzewa.
  4. Zapewniam cię że skonwertowanie wczytanego wiersza na obiekt potrwa krócej niż wczytanie tegoż wiersza, więc jeden wątek konwertujący w zupełności wystarczy.
0

@kq dzięki za wskazówkę. Chyba właśnie o to chodziło ;-).

_13th_Dragon napisał(a):

Nie dziel zadania ma zbyt małe porcje - to powoduje że więcej tracisz na synchronizacji niż zyskujesz na równoległych obliczeniach.

Rozumiem, że piszesz o wielkości bufora? Jeśli tak to docelowo będzie na pewno dużo większy ;-). Mały bufor był tylko do testów.

_13th_Dragon napisał(a):

Nie próbuj odczytywać pliku wielowątkowo - to mija się z celem, ponieważ system i tak odczytuje dysk jednowątkowo na dodatek bardzo wolno..

Ale ja nie zamierzam odczytywać pliku wielowątkowo. Idea jest taka, że jeden wątek odczytuje a reszta konwertuje ;-). Jak będzie odpowiednio duży bufor to myślę, że ma to sens.

_13th_Dragon napisał(a):

"... wielowątkowe liczenie wierszy w pliku (by wiedzieć jak dużą tablicę obiektów mam stworzyć)." - samo liczenie wierszy w pliku aby później czytać go raz jeszcze to już wielki bubel projektowy. Czytaj i od razu dodawaj do wektora, listy, drzewa.

No tak, ale plik będzie miał kilka milionów wierszy. A powiększający się co chwila vector to chyba kiepski pomysł. Lista jest znacznie lepsza w tym wypadku, ale mniej wygodna później - więc jednak wolę wektor ;-) - policzenie wierszy to nic wielkiego :P

_13th_Dragon napisał(a):

Zapewniam cię że skonwertowanie wczytanego wiersza na obiekt potrwa krócej niż wczytanie tegoż wiersza, więc jeden wątek konwertujący w zupełności wystarczy.

No właśnie moim celem jest m.in. przeprowadzenie testów wydajnościowych ;P. Jeśli efekty nie będą znaczące to zostanę przy jednym wątku. Problem jest taki, że plik z około 1 mln-em wierszy wczytuje się ponad 2 sekundy a docelowo pliki będą dużo większe (około 1GB).
Co ciekawe wczytywanie tych danych np. przez strumienie trwałoby znacznie dłużej (100 000 danych wczytywało się bodajże około 8 sekund) - dopiero zastosowanie własnej funkcji konwertującej przyniosło dobry efekt ;)

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