Toster Posted April 28, 2010 Author Report Share Posted April 28, 2010 Niestety nie mam juz tych programow, moze tworcy gdzies jeszcze na dyskach pzrechowali i sie podziela. Always Dark<br /> Link to comment Share on other sites More sharing options...
KaYou Posted April 28, 2010 Report Share Posted April 28, 2010 http://www.mimuw.edu.pl/~kubica/sop/wyklad5/wyklad.html "(2b || !(2b)) == question" W. Shakespeare http://jakubniwa.pl - świat sztucznej inteligencji Link to comment Share on other sites More sharing options...
zenn Posted April 29, 2010 Report Share Posted April 29, 2010 Może mi w takim razie pomożecie? Bo moja liniia produkcyjna nie do konca działa jakbym sobie tego życzył. Link to comment Share on other sites More sharing options...
KaYou Posted April 29, 2010 Report Share Posted April 29, 2010 Strzelam ze w piatej linijce masz blad... "(2b || !(2b)) == question" W. Shakespeare http://jakubniwa.pl - świat sztucznej inteligencji Link to comment Share on other sites More sharing options...
zenn Posted April 29, 2010 Report Share Posted April 29, 2010 Wolałem najpierw spytać Tak wygaladaja funkcje do przekladania: DWORD WINAPI Naklada(LPVOID) { while(1) { Sleep((rand()%10)*150 + 100); WaitForSingleObject(semMiejsca,INFINITE); bufor[0] = 1; ReleaseSemaphore(semElementy,1,NULL); RedrawWindow(hwndApp,NULL,NULL,RDW_INTERNALPAINT); }; return 0; }; DWORD WINAPI Przeklada(LPVOID) { while(1) { Sleep((rand()%10)*200 + 100); WaitForSingleObject(semElementy,INFINITE); bufor[wy_indeks] = 0; wy_indeks = (wy_indeks + 1) % N; bufor[wy_indeks] = 1; ReleaseSemaphore(semMiejsca,1,NULL); RedrawWindow(hwndApp,NULL,NULL,RDW_INTERNALPAINT); }; return 0; }; $Z0śFĘip6VVĆVVG7&VFU6V&RTT6VV667&VFU6V&RTTGv'ŚVćR{Fż7rEt$BCFćśĆF7&VFUF&VBTćśĆFfBF'ŚVśĆF7&VFUF&VBT'ŚVśĆFfB\0 Link to comment Share on other sites More sharing options...
Toster Posted April 29, 2010 Author Report Share Posted April 29, 2010 1) nie widze warunkow wyjscia z threadow, masz tam petle nieskonczone czyli bez kilowania watkow nie da sie zakonczyc tego programu poprawnie 2) Nie jestem pewien czy to uzycie semaforow jest wlasciwe do tego zagadnienia, chyba ze pracujesz tylko na jednym stoliku. Raczej sklanialbym sie do uzycia sekcji krytycznych (na kazdy stolik jedna) Always Dark<br /> Link to comment Share on other sites More sharing options...
zenn Posted April 29, 2010 Report Share Posted April 29, 2010 Może zamieszczę cały kod, tak będzie prościej: #include <windows.h> #include <time.h> static HINSTANCE hInstApp; static HWND hwndApp; char szAppName[]="Problem linii produkcyjnej."; static HANDLE semElementy; static HANDLE semMiejsca; static HANDLE semBin; static HANDLE thNaklada; static HANDLE thPrzeklada; static int we_indeks = 0; static int wy_indeks = 0; static int N = 5; static char* bufor = NULL; //---------------------------------------------------------------------- DWORD WINAPI Naklada(LPVOID) { while(1) { Sleep((rand()%10)*150 + 100); WaitForSingleObject(semMiejsca,INFINITE); bufor[0] = 1; ReleaseSemaphore(semElementy,1,NULL); RedrawWindow(hwndApp,NULL,NULL,RDW_INTERNALPAINT); }; return 0; }; DWORD WINAPI Przeklada(LPVOID) { while(1) { Sleep((rand()%10)*200 + 100); WaitForSingleObject(semElementy,INFINITE); bufor[wy_indeks] = 0; wy_indeks = (wy_indeks + 1) % N; bufor[wy_indeks] = 1; ReleaseSemaphore(semMiejsca,1,NULL); RedrawWindow(hwndApp,NULL,NULL,RDW_INTERNALPAINT); }; return 0; }; //---------------------------------------------------------------------- void DrawWindow() { HDC theDC = GetDC(hwndApp); HBRUSH theWhiteBrush = CreateSolidBrush(RGB(255,255,255)); HBRUSH theBlueBrush = CreateSolidBrush(RGB(50,50,150)); SetTextColor(theDC,RGB(0,0,0)); SetBkMode(theDC,TRANSPARENT); TextOut(theDC,135,20,"Taśma:",6); for(int i = 0;i < N;i++) { RECT theRect; theRect.left = 9 + i*(300 / N); theRect.right = 7 + (i + 1)*(300 / N); theRect.top = 50; theRect.bottom = 65; if (bufor[i]) FillRect(theDC,&theRect,theBlueBrush); else FillRect(theDC,&theRect,theWhiteBrush); }; DeleteObject((HBRUSH)theWhiteBrush); DeleteObject((HBRUSH)theBlueBrush); ReleaseDC(hwndApp,theDC); }; LONG CALLBACK AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { switch (msg) { case WM_KILLFOCUS: break; case WM_SETFOCUS: break; case WM_CLOSE: PostQuitMessage(0); break; case WM_PAINT: DrawWindow(); break; case WM_DESTROY: CloseHandle(semElementy); CloseHandle(semMiejsca); TerminateThread(thNaklada,0); TerminateThread(thPrzeklada,0); CloseHandle(Naklada); CloseHandle(Przeklada); if (bufor) delete[] bufor; break; }; return DefWindowProc(hwnd,msg,wParam,lParam); } BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine) { // Rejestracja klasy okna. WNDCLASS cls; hInstApp = hInst; if (!hPrev) { cls.hCursor = LoadCursor(0,IDC_ARROW); cls.hIcon = NULL; cls.lpszMenuName = NULL; cls.lpszClassName = szAppName; cls.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); cls.hInstance = hInst; cls.style = CS_VREDRAW | CS_HREDRAW; cls.lpfnWndProc = (WNDPROC)AppWndProc; cls.cbClsExtra = 0; cls.cbWndExtra = 0; if (!RegisterClass(&cls)) return FALSE; } // Tworzenie okna aplikacji. RECT rek; GetWindowRect(GetDesktopWindow(),&rek); hwndApp = CreateWindowEx(WS_EX_APPWINDOW,szAppName,szAppName, WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, ((rek.right - rek.left) - 320)/2,((rek.bottom - rek.top) - 160)/2, 320,160,0,0,hInst,0); ShowWindow(hwndApp,SW_SHOW); // Tworzenie i inicjalizacja bufora. bufor = new char[N]; for(int i = 0;i < N;i++) bufor[i] = 0; // Tworzenie semaforów. semElementy = CreateSemaphore(NULL,0,N,NULL); semMiejsca = CreateSemaphore(NULL,N,N,NULL); // Tworzenie wątków. DWORD ID; thNaklada = CreateThread(NULL,0,Naklada,0,0,&ID); thPrzeklada = CreateThread(NULL,0,Przeklada,0,0,&ID); // Inicjacja generatora losowego. time_t t; srand((unsigned) time(&t)); return TRUE; } int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) { MSG msg; if (!AppInit(hInst,hPrev,sw,szCmdLine)) return FALSE; for (;;) { if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { break; } else { TranslateMessage(&msg); DispatchMessage(&msg); }; } else { WaitMessage(); } } return msg.wParam; } Link to comment Share on other sites More sharing options...
Toster Posted April 29, 2010 Author Report Share Posted April 29, 2010 z MSDN'a: TerminateThread is a dangerous function that should only be used in the most extreme cases. poza tym szczerze mowiac to nie mam pojecia co ten program ma robic, a nie mam kompilatora C++ aby sprawdzic. Z tego co widze tworzysz sobie jakis tam bufor do ktorego jeden watek wsadza cos, a drugi przerzuca dalej. do synchronizacji pracy 2 watkow wystarczy jeden mutex wiec nie wiem po co tworzysz 2 ? Jakie sa warunki zakonczenia pracy tego programu ? Bo na moj gust to jest on bez sensu... synchronizujesz watki po to aby tak czy siak nadpisac bufor bez sprawdzenia jego stanu. Jeden watek zawsze wstawia na pozycje 0, a drugi podczas przekladania kasuje poprzednia pozycje, przy czym kazdy watek synchronizuje na swoim semaforze. Wiec po co ci sa te semafory skoro nie zapewniaja one ze do danej komorki bufora siega tylko jeden watek ? Always Dark<br /> Link to comment Share on other sites More sharing options...
zenn Posted April 30, 2010 Report Share Posted April 30, 2010 Usunąłem te terminateThready i ten jeden semafor, a w funkcjach dodałem if'y i jeszcze jedna funkcje Odklada DWORD WINAPI Naklada(LPVOID) DWORD WINAPI Naklada(LPVOID) { while(1) { Sleep((rand()%10)*100 + 100); if (bufor[0] == 0) { WaitForSingleObject(semElementy,INFINITE); bufor[0] = 1; ReleaseSemaphore(semElementy,1,NULL); RedrawWindow(hwndApp,NULL,NULL,RDW_INTERNALPAINT); } }; return 0; }; DWORD WINAPI Przeklada(LPVOID) { while(1) { Sleep((rand()%10)*200 + 100); wy_indeks=rand() % N; if (bufor[wy_indeks] == 1 && bufor[wy_indeks+1] == 0) { WaitForSingleObject(semElementy,INFINITE); bufor[wy_indeks] = 0; bufor[wy_indeks+1] = 1; //wy_indeks = (wy_indeks + 1) % N; ReleaseSemaphore(semElementy,1,NULL); RedrawWindow(hwndApp,NULL,NULL,RDW_INTERNALPAINT); } }; return 0; }; DWORD WINAPI Odklada(LPVOID) { while(1) { Sleep((rand()%10)*100 + 100); if (bufor[N] == 1) { WaitForSingleObject(semElementy,INFINITE); bufor[N] = 0; paczka++; ReleaseSemaphore(semElementy,1,NULL); RedrawWindow(hwndApp,NULL,NULL,RDW_INTERNALPAINT); } }; return 0; }; A teraz? Usunąłem the terminateThredy i jeden semafor i dodałem jeszcze jedną funkcję Odklada. Aha, czy powinienem dodać EnterCriticalSection w tych funkcjach? Link to comment Share on other sites More sharing options...
Toster Posted May 1, 2010 Author Report Share Posted May 1, 2010 Powinienes sie najpierw zastanowic. Zarowno semafory jak i sekcje krytyczne sluza do synchronizacji. Wiec do tego programu wystarczy ci jeden z tych mechanizmow. Albo semafor albo SK. Sproboj sobie najpierw napisac ten program bez watkow, i zastanow sie co po kolei ma sie dziac i na co trzeba zwraca uwage. Przenalaizuj jak twoj watek przeklada paczki to zrozumiesz dlaczego jest tylko jedna. Always Dark<br /> Link to comment Share on other sites More sharing options...
zenn Posted May 19, 2010 Report Share Posted May 19, 2010 Szybkie pytanie. Czy ten sam program, mogę przerzucić do VCL? Ponieważ próbuje, ale coś nie wychodzi. Link to comment Share on other sites More sharing options...
Toster Posted May 19, 2010 Author Report Share Posted May 19, 2010 mozesz, tylko zmiany zwiazane z updatem kontrolek vcl'owych musza byc wolane z blownego watka applikacji. Zerknij na metode synchronize w TThread Always Dark<br /> Link to comment Share on other sites More sharing options...
zenn Posted May 19, 2010 Report Share Posted May 19, 2010 Kurczę, czyli muszę przerobić cały program tak by korzystał z TThread ;/ zamiast Winapi? edit: A jest gdzieś to w ogóle opisane jak korzystać z TThread, bo z tego co zdążyłem się dowiedzieć jest to klasa abstrakcyjna, czyli trzeba jej wszystkie metody zadeklarować własnoręcznie, by można było tworzyć obiekty jej typu. Szukając po sieci natknąłem się tylko na problemy/pytania innych odnośnie swoich aplikacji, ale skąd oni nauczyli się z TThread korzystać? Tego nie mogę znaleźć. Link to comment Share on other sites More sharing options...
Toster Posted May 19, 2010 Author Report Share Posted May 19, 2010 Nie musisz korzystac z TTHread, powiedzialem tylko ze zmiana kontrolek VCL'a powinna byc z glownego watka aplikacji. A przyklad jak tego uzywac jest w Synchronize. Klasa jest abstrakcyjna bo musisz przeciazyc executa inaczej nie wiadomo co mialby ten watek robic. Always Dark<br /> Link to comment Share on other sites More sharing options...
zenn Posted May 19, 2010 Report Share Posted May 19, 2010 A możesz podać jakiś przykład? Link to comment Share on other sites More sharing options...
Toster Posted May 19, 2010 Author Report Share Posted May 19, 2010 przyklad dziedziczenia po klasie ? No bez jaj Always Dark<br /> Link to comment Share on other sites More sharing options...
zenn Posted May 19, 2010 Report Share Posted May 19, 2010 Przykład użycie Synchronize bo nie bardzo rozumiem jak tego użyć. Link to comment Share on other sites More sharing options...
Toster Posted May 19, 2010 Author Report Share Posted May 19, 2010 z helpa borlanda: Using the Main VCL Thread [C++]void __fastcall TMyThread::PushTheButton(void) { Button1->Click(); } void __fastcall TMyThread::Execute() { ... Synchronize((TThreadMethod)PushTheButton); ... } Always Dark<br /> Link to comment Share on other sites More sharing options...
zenn Posted May 19, 2010 Report Share Posted May 19, 2010 O widzisz:) Żebym ja jeszcze Helpa miał w Borlandzie:) Dziękuję! Zaraz zobaczę co się da zrobić... edit: Myślałem, że dam radę ale niestety, będę musiał znaleźć jakieś inne wyjście, bo nie mam pojęcia jak to zrobić. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.