Проблема с многопточностью. Borland C++ Builder

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by mailbrush, 4 Apr 2010.

  1. mailbrush

    mailbrush Well-Known Member

    Joined:
    24 Jun 2008
    Messages:
    1,997
    Likes Received:
    996
    Reputations:
    155
    Возникла проблема с многопоточностью. Есть 100-поточная программа, которая для теста обращается к странице http://example.com. Проблема в том, что при первом нажатие кнопки (код ниже) происходит не 100, а рандумное количество запросов до 100 (н.п. 84, 95, 66, 52)... При втором же - ровно 100, как положено. Отснифал Process Explorer'ом - потоки создаются все, но вот запросы идут не все. И это только при ПЕРВОМ нажатии кнопки. При втором и всем последующим все идет как надо. Почему? Буду очень благодарен за помощь. Использую Borland C++ Builder 6.

    Вот код запуска потоков:
    PHP:
    TMyThread Thr[1000];
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    int i;

    for(
    i=0;i<100;i++)
    Thr[i] = new TMyThread(false);
    }
    Вот метод Execute:
    PHP:
    void __fastcall TMyThread::Execute()
    {
     
    HINSTANCE libcurl NULL;
         if((
    libcurl LoadLibrary"libcurl.dll" )) == NULL)
              
    MessageBox(NULL"ы"MB_OK0);

         
    CURL*(__stdcall *curl_easy_init)();
         
    CURLcode(__stdcall *curl_easy_setopt )(CURL *curlCURLoption option, ...);
         
    CURLcode (__stdcall *curl_easy_perform )(CURL *curl);
         
    void (__stdcall *curl_easy_cleanup )(CURL *curl);
         
    curl_easy_init=(CURL*(__stdcall*)())GetProcAddress(libcurl"curl_easy_init" );
         
    curl_easy_setopt=(CURLcode(__stdcall *)(CURL *curlCURLoption option, ...))
         
    GetProcAddress(libcurl"curl_easy_setopt");
         
    curl_easy_perform=(CURLcode(__stdcall *)(CURL *curl))GetProcAddress(libcurl"curl_easy_perform" );
         
    curl_easy_cleanup=(void (__stdcall *)(CURL *curl))GetProcAddress(libcurl"curl_easy_cleanup" );

    CURL *curl;
    curl curl_easy_init();
    curl_easy_setopt(curlCURLOPT_URL"http://www.example.com/");
    curl_easy_setopt(curlCURLOPT_WRITEFUNCTIONWriter);
    curl_easy_setopt(curlCURLOPT_WRITEDATA, &table);
    curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    }
     
  2. Meecript_

    Meecript_ Banned

    Joined:
    29 Oct 2008
    Messages:
    194
    Likes Received:
    62
    Reputations:
    32
    Этот код сделай в крит.секции:
    Code:
    HINSTANCE libcurl = NULL; 
         if((libcurl = LoadLibrary( "libcurl.dll" )) == NULL) 
              MessageBox(NULL, "ы", MB_OK, 0); 
    
         CURL*(__stdcall *curl_easy_init)(); 
         CURLcode(__stdcall *curl_easy_setopt )(CURL *curl, CURLoption option, ...); 
         CURLcode (__stdcall *curl_easy_perform )(CURL *curl); 
         void (__stdcall *curl_easy_cleanup )(CURL *curl); 
         curl_easy_init=(CURL*(__stdcall*)())GetProcAddress  (libcurl, "curl_easy_init" ); 
         curl_easy_setopt=(CURLcode(__stdcall *)(CURL *curl, CURLoption option, ...)) 
         GetProcAddress(libcurl, "curl_easy_setopt"); 
         curl_easy_perform=(CURLcode(__stdcall *)(CURL *curl))GetProcAddress(libcurl, "curl_easy_perform" ); 
         curl_easy_cleanup=(void (__stdcall *)(CURL *curl))GetProcAddress(libcurl, "curl_easy_cleanup" );
     
  3. mailbrush

    mailbrush Well-Known Member

    Joined:
    24 Jun 2008
    Messages:
    1,997
    Likes Received:
    996
    Reputations:
    155
    M_script_, не помогает.

    Вот так сделал:
    PHP:
    EnterCriticalSection(&Form1->CS);
     
    HINSTANCE libcurl NULL;
         if((
    libcurl LoadLibrary"libcurl.dll" )) == NULL)
              
    MessageBox(NULL"û"MB_OK0);

         
    CURL*(__stdcall *curl_easy_init)();
         
    CURLcode(__stdcall *curl_easy_setopt )(CURL *curlCURLoption option, ...);
         
    CURLcode (__stdcall *curl_easy_perform )(CURL *curl);
         
    void (__stdcall *curl_easy_cleanup )(CURL *curl);
         
    curl_easy_init=(CURL*(__stdcall*)())GetProcAddress(libcurl"curl_easy_init" );
         
    curl_easy_setopt=(CURLcode(__stdcall *)(CURL *curlCURLoption option, ...))
         
    GetProcAddress(libcurl"curl_easy_setopt");
         
    curl_easy_perform=(CURLcode(__stdcall *)(CURL *curl))GetProcAddress(libcurl"curl_easy_perform" );
         
    curl_easy_cleanup=(void (__stdcall *)(CURL *curl))GetProcAddress(libcurl"curl_easy_cleanup" );
    LeaveCriticalSection(&Form1->CS);
    А в Unit1.h прописал:
    PHP:
    public:        // User declarations
            
    CRITICAL_SECTION CS;
    За первым разом только что выполнилось 84 запроса, нажал еще раз - ровно 100.
     
  4. Meecript_

    Meecript_ Banned

    Joined:
    29 Oct 2008
    Messages:
    194
    Likes Received:
    62
    Reputations:
    32
    Уверен на 99.9%, что ты забыл про InitializeCriticalSection(&CS); =)
    (перед запуском потоков в Button1Click)
     
    #4 Meecript_, 4 Apr 2010
    Last edited: 4 Apr 2010
  5. mailbrush

    mailbrush Well-Known Member

    Joined:
    24 Jun 2008
    Messages:
    1,997
    Likes Received:
    996
    Reputations:
    155
    Сделал я это, только не в Button1Click, а в
    Вот щас перенес инициализацию в Button1Click. Заметил, что колличество запросов увеличилось до 90-95. Но никак не 100, как мне требовалось. За вторым и последующими нажатиями все ок (ровно 100), как и было раньше.

    M_script_, зайди, пожалуйста, в ICQ, или напиши мне в 674542, не могу до тебя достучатся.
     
    #5 mailbrush, 4 Apr 2010
    Last edited: 4 Apr 2010
  6. mailbrush

    mailbrush Well-Known Member

    Joined:
    24 Jun 2008
    Messages:
    1,997
    Likes Received:
    996
    Reputations:
    155
    Фух, решил проблему. Спасибо, M_script_.
    Вот рабочий метод Execute():
    PHP:
    void __fastcall TMyThread::Execute()
    {
    EnterCriticalSection(&Form1->CS);
     
    HINSTANCE libcurl NULL;
         if((
    libcurl LoadLibrary"libcurl.dll" )) == NULL)
              
    MessageBox(NULL"û"MB_OK0);

         
    CURL*(__stdcall *curl_easy_init)();
         
    CURLcode(__stdcall *curl_easy_setopt )(CURL *curlCURLoption option, ...);
         
    CURLcode (__stdcall *curl_easy_perform )(CURL *curl);
         
    void (__stdcall *curl_easy_cleanup )(CURL *curl);
         
    curl_easy_init=(CURL*(__stdcall*)())GetProcAddress(libcurl"curl_easy_init" );
         
    curl_easy_setopt=(CURLcode(__stdcall *)(CURL *curlCURLoption option, ...))
         
    GetProcAddress(libcurl"curl_easy_setopt");
         
    curl_easy_perform=(CURLcode(__stdcall *)(CURL *curl))GetProcAddress(libcurl"curl_easy_perform" );
         
    curl_easy_cleanup=(void (__stdcall *)(CURL *curl))GetProcAddress(libcurl"curl_easy_cleanup" );

    CURL *curl;
    curl curl_easy_init();
    LeaveCriticalSection(&Form1->CS); 
    curl_easy_setopt(curlCURLOPT_URL"http://www.example.com/");
    curl_easy_setopt(curlCURLOPT_WRITEFUNCTIONWriter);
    curl_easy_setopt(curlCURLOPT_WRITEDATA, &table);
    curl_easy_perform(curl);
    curl_easy_cleanup(curl);
    }