2012-01-31 14 views
9

मैं एक PHP स्क्रिप्ट लिखने की कोशिश कर रहा हूं जिसे मैं सुनिश्चित करना चाहता हूं कि किसी भी समय किसी भी समय इसे चलाने का एक उदाहरण हो। लॉकिंग के विभिन्न तरीकों, और दौड़ की स्थिति, आदि इत्यादि के बारे में यह सब बात मुझे इच्छाएं दे रही है।PHP लॉकिंग/सुनिश्चित करना कि किसी दिए गए स्क्रिप्ट को किसी भी समय दिए गए किसी भी समय

मैं करने के लिए ताला फ़ाइलों जाने का रास्ता नहीं है, या संकेतबाहु, या MySQL ताले का उपयोग कर, या आदि आदि आदि

किसी को भी मुझे बता सकते हैं के रूप में उलझन में हूँ:

क) सही इसे लागू करने का तरीका है?

और

ख) मुझे एक PHP कार्यान्वयन (या PHP के लिए बंदरगाह के लिए आसान कुछ करने के लिए प्वाइंट?)

+2

चालू स्क्रिप्ट है द्वारा असफल हो जायेगी? –

+0

यदि यह वास्तव में मायने रखता है ... वेब सर्वर। –

+1

शायद एक MySQL लॉक, उस स्थिति में, इसलिए स्क्रिप्ट कृपा से निरस्त हो सकती है और "उपयोग में डर" कह सकती है। झुंड का उपयोग करके और जैसे ही स्क्रिप्ट को अपाचे से बंद कर दिया जाएगा और संभवतः 500 आंतरिक त्रुटियों और क्या नहीं होगा। –

उत्तर

0

आप समाधान है कि सबसे अच्छा अपनी परियोजना, दो सरल है कि प्राप्त करने के लिए तरीके से फिट बैठता है के लिए जा सकते हैं फ़ाइल लॉकिंग या डेटाबेस लॉकिंग हैं।

ताला फ़ाइल के कार्यान्वयन के लिए, जाँच http://us2.php.net/flock

आप पहले से ही, एक डेटाबेस का उपयोग एक तालिका बनाने, कि स्क्रिप्ट के लिए जाना जाता टोकन बनाएं, यह वहाँ डाल दिया, और सिर्फ स्क्रिप्ट के अंत के बाद उसे निकाल दें। त्रुटियों पर समस्याओं से बचने के लिए, आप समाप्ति समय का उपयोग कर सकते हैं।

+0

क्या आप वाकई इसे संभालने का एक सुरक्षित तरीका है? PHP.net पर टिप्पणियों में कई प्रविष्टियां हैं जो दर्शाती हैं कि यह दौड़ की स्थिति पेश कर सकती है। –

1
// borrow from 2 anwsers on stackoverflow 
function IsProcessRunning($pid) { 
    return shell_exec("ps aux | grep " . $pid . " | wc -l") > 2; 
} 

function AmIRunning($process_file) { 
    // Check I am running from the command line 
    if (PHP_SAPI != 'cli') { 
     error('Run me from the command line'); 
     exit; 
    } 

    // Check if I'm already running and kill myself off if I am 
    $pid_running = false; 
    $pid = 0; 
    if (file_exists($process_file)) { 
     $data = file($process_file); 
     foreach ($data as $pid) { 
      $pid = (int)$pid; 
      if ($pid > 0 && IsProcessRunning($pid)) { 
       $pid_running = $pid; 
       break; 
      } 
     } 
    } 
    if ($pid_running && $pid_running != getmypid()) { 
     if (file_exists($process_file)) { 
      file_put_contents($process_file, $pid); 
     } 
     info('I am already running as pid ' . $pid . ' so stopping now'); 
     return true; 
    } else { 
     // Make sure file has just me in it 
     file_put_contents($process_file, getmypid()); 
     info('Written pid with id '.getmypid()); 
     return false; 
    } 
} 

/* 
* Make sure there is only one instance running at a time 
*/ 
$lockdir = '/data/lock'; 
$script_name = basename(__FILE__, '.php'); 
// The file to store our process file 
$process_file = $lockdir . DS . $script_name . '.pid'; 

$am_i_running = AmIRunning($process_file); 
if ($am_i_running) { 
    exit; 
} 
0

आप लिनक्स पर php का उपयोग कर रहे मामले में काम कर सकता था और मुझे लगता है कि सबसे व्यावहारिक तरीका है:

<?php 
if(shell_exec('ps aux | grep '.__FILE__.' | wc -l')>3){ 
    exit('already running...'); 
} 
?> 

एक और तरीका है करने के लिए क्या यह फ़ाइल ध्वज और बाहर निकलने के कॉलबैक के साथ है, निकास कॉलबैक यह सुनिश्चित करेगा कि फ़ाइल ध्वज PHP निष्पादन अंत के किसी भी मामले में 0 पर रीसेट हो जाएगा एल त्रुटियां

<?php 
function exitProcess(){ 
    if(file_get_contents('inprocess.txt')!='0'){ 
    file_put_contents('inprocess.txt','0'); 
    } 
} 

if(file_get_contents('inprocess.txt')=='1'){ 
    exit(); 
} 

file_put_contents('inprocess.txt','1'); 
register_shutdown_function('exitProcess'); 

/** 
execute stuff 
**/ 
?> 
0

एक तरह से php समारोह एक डमी फ़ाइल, कि एक प्रहरी के रूप में कार्य के साथ झुंड उपयोग करने के लिए है।

हमारा काम की शुरुआत, यदि फ़ाइल एक LOCK_EX झंडा, बाहर निकलें उठाना, या प्रतीक्षा करें, किया जा सकता है।

Php झुंड प्रलेखन: http://php.net/manual/en/function.flock.php

इस उदाहरण के लिए, एक फ़ाइल lock.txt पहले बनाया जाना चाहिए कहा जाता है।

उदाहरण 1, यदि कोई और जुड़वां प्रक्रिया चल रही है, तो यह एक राज्य संदेश देने के बिना ठीक से बाहर निकल जाएगी।

यह त्रुटि स्थिति फेंक देगा, अगर फ़ाइल lock.txt पहुंच योग्य नहीं है।

<?php 

$fp = fopen("lock.txt", "r+"); 

if (!flock($fp, LOCK_EX|LOCK_NB, $blocked)) { 
    if ($blocked) { 

     // another process holds the lock 
     echo "Couldn't get the lock! Other script in run!\n"; 

    } 
    else { 
     // couldn't lock for another reason, e.g. no such file 
     echo "Error! Nothing done."; 
    } 
} 
else { 
    // lock obtained 
    ftruncate($fp, 0); // truncate file 

    // Your job here 
    echo "Job running!\n"; 

    // Leave a breathe 
    sleep(3); 

    fflush($fp);   // flush output before releasing the lock 
    flock($fp, LOCK_UN); // release the lock 

} 

fclose($fp); // Empty memory 

उदाहरण 2, हम, कतार के बाद एक निष्पादन के लिए प्रतीक्षा करने के लिए प्रक्रिया, चाहता है यदि कोई हो:,

<?php 

$fp = fopen("lock.txt", "r+"); 

if (flock($fp, LOCK_EX)) { // acquire an exclusive lock 
    ftruncate($fp, 0);  // truncate file 

    // Your job here 
    echo "Job running!\n"; 

    // Leave a breathe 
    sleep(3); 

    fflush($fp);   // flush output before releasing the lock 
    flock($fp, LOCK_UN); // release the lock 
} 

fclose($fp); 

यह भी fopen एक्स मोड में साथ संभव है स्क्रिप्ट समाप्त होने पर फ़ाइल बनाने और मिटाकर।

केवल लेखन के लिए बनाएं और खोलें; फाइल पॉइंटर को फ़ाइल की शुरुआत पर रखें। फ़ाइल पहले से मौजूद हैं, तो fopen() कहते हैं एक वेबसर्वर, या कमांड लाइन के तहत गलत लौटने

http://php.net/manual/en/function.fopen.php

संबंधित मुद्दे