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

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by mailbrush, 25 Sep 2009.

  1. Hiro Protagonist

    Joined:
    26 Aug 2009
    Messages:
    132
    Likes Received:
    24
    Reputations:
    -2
    2Ra$cal

    мьютексы намного тормознее интерлокеда и в этом примере не надо их применять.

    2mailbrush

    1. Ааа, я понял. Тебе нужно чтобы несколько потоков обрабатывали некий диапазон. Дык разбивай диапазон этот на части и передавай поддиапазон (начало/размер) в поток. Там локальной переменной присваивай начальный uid диапазона и в цикле проходи все. Тогда тебе ненужна синхронизация и глобальная переменная. А то в начале у тебя код другое подразумевал ).

    2. пример с передачей параметров в поток я приводил на первой странице.
     
  2. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Ага. Можно сделать еще так: объявить какую-нибудь структуру с двумя значениями: startid и increment и в последующем передавать ее в поток. Соответственно в первое значение записываем начальное значение id, во вторую, - шаг изменения значения. То есть, если создать 5 потоков, каждому присвоить начальные значения id, как 1, 2, 3, 4, 5, значение инкремента установить в 5, то получится, что первый поток обработает следующие id пользователей: 1, 6, 11... второй: 2, 7, 12... пятый: 5, 10, 15 и т. д. Я использовал этот способ в некоторых своих программах, все работало отлично и исправно.
     
  3. mailbrush

    mailbrush Well-Known Member

    Joined:
    24 Jun 2008
    Messages:
    1,997
    Likes Received:
    996
    Reputations:
    155
    В точку! Но опять какая-то фигня... Параметры не передаются, решил сделать по-другому, но и здесь не пашет...

    Функция, которая вызывает поток:
    Code:
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    start[0]=0;
    start[1]=20;
    start[2]=40;
    start[3]=60;
    
    end[0]=20;
    end[1]=40;
    end[2]=60;
    end[3]=80;
    //InitializeCriticalSection( &cs );
    for(i=1;i<=4;i++)
    {
    _beginthread(tfunc, 0, NULL);
    }
    }
    Глоб. переменные:
    Code:
    volatile long uid = 1;
    CRITICAL_SECTION cs;
    int i;
    int myID = 0;
    int *start = (int*)malloc(5*4);
    int *end = (int*)malloc(5*4);
    Сам поток:
    Code:
    void tfunc(void *argv)
    {
    int j;
    char request[1024*5], response[1024*5];
    int first, second;
    char* headers;
    myID =  InterlockedIncrement(&uid) - 1;
    sockaddr_in s_a;
    WSADATA wd;
    WSAStartup( MAKEWORD( 2, 2 ), &wd );
    
    for(j=start[myID]-1;j<=end[myID];j++)
    {
    SOCKET s = socket( AF_INET, SOCK_STREAM, 0 );
    if (s == INVALID_SOCKET)
    ShowMessage("INVALID");
    s_a.sin_addr.s_addr = inet_addr( "89.188.109.206" );
    s_a.sin_port = htons( 80 );
    s_a.sin_family = AF_INET;
    if (connect( s, (struct sockaddr*)&s_a, sizeof( s_a ) ) == SOCKET_ERROR)
    ShowMessage("Bad Connect!");
    sprintf( request, "GET /forum/profile.php?mode=viewprofile&u=%i HTTP/1.1\r\nHost: tfile.ru\r\nConnection: Close\r\n\r\n", j);
    send( s, request, strlen( request ), 0 );
    //EnterCriticalSection( &cs );
    for(i=0;i<=10;i++)
    recv( s, response, 1024 , 0 );
    //LeaveCriticalSection( &cs );
    closesocket( s );
    }
    WSACleanup(); //
    }
    Вообще хз как работает...

    Буду преблагодарен за помощь...
     
  4. Ra$cal

    Ra$cal Elder - Старейшина

    Joined:
    16 Aug 2006
    Messages:
    670
    Likes Received:
    185
    Reputations:
    78
    Code:
    #include <iostream>
    #include <process.h>
    using namespace std;
    
    unsigned __stdcall SecondThreadFunc( void* pArguments )
    {
    	int* param_index = (int*)pArguments;
    	int local_index = *param_index;
    	delete param_index;
    
    	cout << local_index << '\n';
    
    	_endthreadex( 0 );
    	return 0;
    }
    
    
    void main()
    {
    	unsigned int threadID;
    	for(int i = 0; i < 5; i++){
    		_beginthreadex( NULL, 0, &SecondThreadFunc, new int(i), 0, &threadID );
    	}
    
    	system("pause");
    }
    На выходе имеем:

    0
    2
    4
    3
    1
    Press any key to continue . . .
     
  5. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,021
    Likes Received:
    1,200
    Reputations:
    327

    утяж аргумент argv == NULL в beginthread, а вообще лучше - апи)