- fastcgi в нескольких потоках, parad, 13:46 , 14-Мрт-12 (1)
лучше бы код привел, а не на память как-то так. зае*бись вопросы пошли.напрашиваются 3 ошибки( в порядке вероятности ): - кладешь в очеред, непроинициализированная FCGX_InitRequest'ом структура копируется, потом ты инициализируешь стековую переменную, а в очереди остается фигня. Тобишь измени порядок вызова FCGX_InitRequest и покладки в очередь. - фцги у тебя работает через std{in,out,err} - должен в многопоточном приложении по сокетам. - конкурентный доступ без блокировки к очереди в многопоточном приложении. учись задавать полные вопросы с описанием.
- fastcgi в нескольких потоках, scx75, 11:10 , 15-Мрт-12 (4)
> - кладешь в очеред, непроинициализированная FCGX_InitRequest'ом структура копируется, > потом ты инициализируешь стековую переменную, а в очереди остается фигня. Тобишь > измени порядок вызова FCGX_InitRequest и покладки в очередь.инициализация есть полный код http://govnokod.com/6123 > - фцги у тебя работает через std{in,out,err} - должен в многопоточном приложении > по сокетам. можно конкретнее? я пробывал вариант где while(FCGX_Request_r(&req) == 0) у каждого потока свой, тогда все отлично работает, но такой вариант не катит > - конкурентный доступ без блокировки к очереди в многопоточном приложении. это все есть, в коде только не привел
- fastcgi в нескольких потоках, parad, 16:26 , 15-Мрт-12 (6)
ну теперь понятней. )у тебя: while(FCGX_Accept_r(&req) == 0) { ... handler_pool_.put_request(req); ... } А вот код из libfcgi: int FCGX_Accept_r(FCGX_Request *reqDataPtr) { FCGX_Finish_r(reqDataPtr); ... } где FCGX_Finish_r() все чистит, закрывает и освобождает память. тобишь поток не успевает ответить, а дескрипторы закрываются, память освобождается. нужно дописать строчку: while(FCGX_Accept_r(&req) == 0) { ... handler_pool_.put_request(req); FCGX_InitRequest( req, ... ); // < по коду фцги - не занимается освобождением ресурсов, такчто подайдет. ... }
- fastcgi в нескольких потоках, parad, 13:52 , 14-Мрт-12 (2)
пс. почему топик в базах данных и sql?
- fastcgi в нескольких потоках, scx75, 14:42 , 15-Мрт-12 (5)
вообщем то виновато что происходит это в следующем порядке:
while(FCGX_Accept_r(&req) == 0) { req2 = req1; FCGX_InitRequest(&req, listen_socket, 0); // переинициализируем чтобы при FCGX_Accept_r не очистились стримы std::string str = "Content-Type: text/html;\r\n\r\nasads"; FCGX_PutStr(str.c_str(), str.size(), req2.out); FCGX_Finish_r(&req2); }
- fastcgi в нескольких потоках, parad, 16:28 , 15-Мрт-12 (7)
- fastcgi в нескольких потоках, scx75, 16:57 , 15-Мрт-12 (8)
> верно.ну да, до этого додумался, а в чем дальше трабл непонятно в FCGX_InitRequest обнуляется память структуры и устанавливаются некоторые значения, но nginx почему то перестает принимает ответ от моей проги - выдает браузеру 502 как при memset'е может затронуться содержимое указателей?
- fastcgi в нескольких потоках, scx75, 16:58 , 15-Мрт-12 (9)
поправка:
while(FCGX_Accept_r(&req) == 0) { req2 = req;
- fastcgi в нескольких потоках, parad, 20:06 , 15-Мрт-12 (10) –1
Поэксперементировал.Натолкнуло на мысль что разработчики fastcgi пи**расы. Полез в код и понял что разбираюсь в людях: Accept_r(reqDataPtr) дергает NewReader(reqDataPtr, ...) для создания потока in, NewReader(reqDataPtr, ...) дергает NewStream(reqDataPtr, ...), который содержит вот такие строчки: -------------- ... FCGX_Stream_Data *data = (FCGX_Stream_Data *)Malloc(sizeof(FCGX_Stream_Data)); data->reqDataPtr = reqDataPtr; // Указатель на себя прикапывают. :) ... -------------- Тобишь паттерт поставщика-потребители в твоей реализации не прокатит. Нельзя реквест трогать, пока не отработает. Вот такой суперкастыль популярен в мире. )) Хоть сам реализовывай.
- fastcgi в нескольких потоках, scx75, 22:36 , 15-Мрт-12 (11)
удивляюсь, как вам не жалко времени на один из 100500 вопросов, спасибо) сейчас попробую понять что написали
- fastcgi в нескольких потоках, parad, 12:03 , 16-Мрт-12 (13)
дело 10мин. сейчас на проекте где предстоит реализовывать компонент над фцги. уже проводил исследовательскую работу на подготовительном этапе - смотрел, пробывал, но в глубь не лазял. отвечая на этот вопрос сам опыту набрался, который скоро пригодится, тк тоже бы первым делом писал один поток-поставщик и пул потоков потребителей. и как следствие словил бы ту-же граблю. такчто незачто. )
- fastcgi в нескольких потоках, scx75, 11:57 , 16-Мрт-12 (12)
и все же не догнал, почему это влияет на результат? там же новые стримы делаются, на стримы req2 никак не должны влиять, не?
- fastcgi в нескольких потоках, parad, 12:06 , 16-Мрт-12 (14)
строчка: FCGX_Accept_r(&req) - вот этот указатель прикапывается внутрях. даже если мы req скопируем куда-либо и занулим его память, внутрях будет использована эта переменная.
- fastcgi в нескольких потоках, scx75, 14:45 , 16-Мрт-12 (15)
это то понятно, но нам не важна сама переменная, указатели на потоки то скопировали в другую, куда и производится вывод
req2 = req; FCGX_InitRequest(&req, listen_socket, 0); // почистили req FCGX_PutStr(str.c_str(), str.size(), req2.out); // выводим в req2, где указатели потоков сохранились и не очищались
- fastcgi в нескольких потоках, parad, 15:58 , 16-Мрт-12 (16)
в том-то и дело, что переменная важна. они прикапывают указатель именно req. И через нее осуществляется доступ к содержимому реквеста:FCGX_PutStr() содержит: stream->emptyBuffProc(stream, FALSE); где, stream->emptyBuffProc - для in отока - NULL, для out потока - указатель на функцию EmptyBuffProc(), которая содержит строчки: -----------------------> *((FCGI_Header *) data->buff) = MakeHeader(data->type, data->reqDataPtr->requestId, cLen, eLen - cLen); -----------------------> if (write_it_all(data->reqDataPtr->ipcFd, (char *)data->buff, stream->wrNext - data->buff) < 0) { -----------------------> тобишь, при записи в out поток используется указатель на структуру запроса для получения идентификатора запроса и дескриптора сокета. Т.к. указатель смотрит на req - в этих местах они для него - 0.
- fastcgi в нескольких потоках, scx75, 16:45 , 16-Мрт-12 (17)
спасибо, добрый чел, теперь дошло)
- fastcgi в нескольких потоках, scx75, 21:35 , 16-Мрт-12 (18)
вставил костыль, где меняю этот указатель на адрес req2 - теперь все пашет
- fastcgi в нескольких потоках, parad, 15:02 , 17-Мрт-12 (19)
не забудь что там еще err и in потоки есть. а вообще хреново костыль костылем закрывать.
- fastcgi в нескольких потоках, scx75, 00:27 , 19-Мрт-12 (20)
куда теперь деваться, какие еще варианты многопоточности с одним приемником можно тогда придумать?
|