Skocz do zawartości

[Mikrokonkurs] linia produkcyjna


Toster

Polecane posty

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 do komentarza
Udostępnij na innych stronach

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 />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

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 do komentarza
Udostępnij na innych stronach

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 />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

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 do komentarza
Udostępnij na innych stronach

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 />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

  • 3 weeks later...

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 do komentarza
Udostępnij na innych stronach

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 />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

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 />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

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 do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...