2011-01-13 7 views
1

내가 루프가 할 말 : 데이터를 사용할 수없는 경우루프의 시간 제한은 어떻게 설정합니까?

$lines = file('file.txt');  

foreach ($lines as $line) { 

    // some function 

} 

일부 시간이 하나 개의 루프를 완료하는 데 시간이 더 걸릴. 그렇다면 각 루프에 시간 제한을 설정하여 정보를 사용할 수 없다면 다음으로 이동할 것입니까?

+0

질문을 즉시 대답 할 수 없으므로 더 많은 코드를 보여줘야합니다. "데이터를 사용할 수없는 경우 하나의 루프를 완료하는 데 시간이 좀 걸리는 경우가 있습니다."현재 게시 된 코드와 관련이 없습니다. – thirtydot

+0

미안하지만 질문을 이해할 수 없습니다. 정교하게 제발 주시겠습니까? – davogotland

답변

5

은 제한 시간으로 해결하지 않습니다.! 시간 제한을 사용하면 장기적으로 모든 종류의 문제가 발생할 수 있습니다. "시간 제한은 코드 냄새"라고 말할만큼 멀리 갈 것입니다.

대신 데이터를 사용할 수 있는지 먼저 확인하고 그렇지 않은 경우 루프하지 마십시오.

+0

루프 내에서 함수에 대해 이야기하고 있습니다 ... 실제로 루프 내부의 함수는 너무 많은 시간이 걸립니다. – mathew

+0

그런 경우 루프 내부에 함수를 표시해야합니다. 하지만 어쨌든, 코드의 시간 제한을 사용하는 것이 가장 흔히 코드 냄새 = 나쁜 것입니다. – markus

1

현재 시간을 루프 앞에 time()과 함께 저장하고 루프 시작 부분에서 현재 시간과 비교하고 설정된 시간이 경과하면 중단합니다.

tharkun이 말했듯이 먼저 데이터가 사용 가능한지 확인해야합니다. 파일이 외부 적으로 변경되면 filemtime()이 떠오른다.

1

타이머를 만드는 대신 데이터를 사용할 수 있는지 테스트해야합니다.

$lines = file('file.txt'); 

if (!empty($lines)) { 
    foreach ($lines as $line) { 
    // some function 
    } 
} 
+0

나는 당신에게 말하는 걸 깜빡 했어. 내가 부르는 기능은 많은 시간을 필요로한다! 파일에 빈 줄이 없습니다 .... 그래서 특정 시간 프레임에 대한 루프에서 함수를 제한해야합니다 ... – mathew

1

foreach를 사용하여 반복을 시도하기 전에 $ lines 배열에 데이터가 있는지 확인하기 만하면됩니다. 예를 들면 :

(메모리에 맞지 않을 수도 있습니다 파일을 사용하여 생성 된 배열), 당신은 파일이 끝날 때까지 한 번에 한 줄을 읽는 동안 루프를 사용해야있는 대용량 파일에 대해 말했다
<?php 
    $lines = file('file.txt'); 
    if (!empty($lines)) { 
     foreach ($lines as $currentLine) { 
      ... 
     } 
    } 
?> 

(EOF) 마커가 발견되었습니다. 예를 들어

: 데이터를 사용할 수없는 경우

<?php 
    $fileHandle = fopen("test.txt"); 
    if(is_resource($fileHandle)) { 
     while (!feof($fileHandle)) { 
      $currentLine = fread($fileHandle); 
     } 
    fclose($handle); 
    } 
?> 
+0

oops 나는 당신에게 .... 걸리는 걸 잊었습니다. 제가 부르는 함수는 많은 시간을 필요로합니다 !!! 파일에 빈 줄이 없습니다 .... 그래서 특정 시간 프레임에 대한 루프에서 함수를 제한해야합니다. ... – mathew

+0

@matthew - 두 번째 방법은 이상적입니다 - 한 번에 한 줄씩 읽을 수 있습니다. 특정 시간 제한이 만료 된 다음 fseek를 사용하여 다음 번 스크립트 실행시 이전 위치로 다시 이동합니다 (DB 또는 파일 등으로 이동할 바이트를 저장해야합니다). –

+0

하지만이 코드로 어떻게 구현합니까 ?? 나는 파일 메모리 문제로 걱정하지 않는다. 나는 루프의 시작 부분에 메모리를 설정한다. – mathew

1

이 코드에 따르면, 루프는 전혀 시작하지 않았다! 그래서 질문을 좀 더 자세하게 작성해야합니다.

2

루프의 내용에 따라 달라집니다. 중첩 루프와 긴 지속 시간은 내부 루프의 반복 횟수로 인해 발생의 경우

, 당신은 당신의 코드 예에서이를 감지 할 수 있습니다

foreach ($lines as $line) { 
    $iters=strtok($line, ','); 
    $start_iter=time(); 
    for ($x=0; $x<$iters; $x++) { 
     ... do something here 
     if (time()-$start_iter>600) { 
      print "abandoning $line after $x iterations\n"; 
      break; 
     } 
    } 
} 

OTOH이 기능이 기본적으로 원자 인 경우 , 예.

foreach ($lines as $line) { 
     mysql_query($line); 
} 

그런 다음 컨트롤은 작업이 완료 될 때까지 절대로 사용자 코드로 돌아 가지 않습니다. 그러나 이것은 처리를 중단하고 다음 라인으로 진행하는 것을 불가능하게한다는 것을 의미하지 않습니다. 다음을 수행하는 두 가지 방법이 있습니다 :

1) pcntl_alarm을 사용하여 신호 처리기를 트리거합니다. 위의 경우 문제 - 시그널 핸들러가 완료되면 호출 된 함수가 재개 될 것이므로 - 어떤 경우에는 겹쳐진 함수의 조기 종료를 강제하는 것이 가능할 수도있다.

2) 루프의 내부 부분을 별도의 프로세스로 실행하고 오버런하는 경우 프로세스를 종료합니다.

자세한 내용은 pcntl 함수를 살펴보십시오. Linux/Unix/POSIX 환경에서만 작동합니다.

관련 문제