API请参考:http://curl.haxx.se/libcurl/c/libcurl-multi.html
官网sample参考:http://curl.haxx.se/libcurl/c/multi-single.html
下面是自己的一个multi接口select IO复用采集例子:
void CMultiGather::PerformRequests()
{
int nStillRunnings = 0;
while(CURLM_CALL_MULTI_PERFORM==
curl_multi_perform(m_pMultiCURL, &nStillRunnings));
if(0 == nStillRunnings)
{
usleep(10000);
return;
}
//fd_set for read,write and exception
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
//fdset & select
int maxfd = 0;
long nTimeout = 0;
CURLMcode nRetCode = curl_multi_fdset(m_pMultiCURL, &fdread, &fdwrite, &fdexcep, &maxfd);
assert(nRetCode == CURLM_OK);
nRetCode = curl_multi_timeout(m_pMultiCURL, &nTimeout);
assert(nRetCode == CURLM_OK);
if (nTimeout == -1 || nTimeout > 5000)
nTimeout = 2000;
if (maxfd == -1)
{
usleep(nTimeout*1000);
}
else
{
struct timeval T;
T.tv_sec = nTimeout/1000;
T.tv_usec = (nTimeout%1000)*1000;
int rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &T);
//assert(rc >= 0);
if(rc > 0)
{
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(m_pMultiCURL, &nStillRunnings));
}
}
/* check whether some conns are timeout or not.*/
map<TConnInfo*,int>::iterator it = m_mConnStatus.begin();
for(; it != m_mConnStatus.end(); it++)
{
TConnInfo* pConn = it->first;
assert(pConn != NULL);
if(it->second == CONN_BUSY)
{
assert(pConn->nStartTime > 0);
time_t nTime = time(0) - pConn->nStartTime;
if(nTime > pConn->pRequest->m_nTransferTimeout)
{
curl_multi_remove_handle(m_pMultiCURL, pConn->pEasyCURL);
SaveConn(pConn, CURLE_OPERATION_TIMEDOUT);
m_qFreeConn.push(pConn);
pConn->nStartTime = 0;
m_mConnStatus[pConn] = 0;
}
}
}
}