2011-04-09 14 views
17

क्या सभी PHP प्रक्रियाओं के बीच चर और सरणी साझा करना संभव है उन्हें डुप्लिकेट किए बिना?सभी PHP प्रक्रियाओं के बीच साझा चर/स्मृति

memcached का उपयोग करना, मुझे लगता है कि पीएचपी प्रयुक्त स्मृति डुप्लिकेट:
$array = $memcache->get('array');
$ सरणी memcached से एक प्रतिलिपि होगी।

तो मेरा विचार है कि स्थिर वेरिएबल जो पहले ही परिभाषित किया गया था, और सभी प्रक्रियाओं के बीच साझा किया जा सकता था।

+1

बड़ा है कि आपके सरणी है - साझा स्मृति ब्लॉक के आकार

  • shmop_write प्राप्त करें? –

  • +0

    हाँ। क्या आप थोड़ा और संदर्भ जोड़ सकते हैं? डेटाबेस में डेटा संग्रहीत करने के बारे में, और वर्तमान स्क्रिप्ट में केवल बिट्स को पुनर्प्राप्त करने के बारे में कैसे? –

    +0

    यह आमतौर पर डेटाबेस में डेटा संग्रहीत करके हल किया जाता है, और केवल वही चीज़ प्राप्त करता है जो आवश्यक है। –

    उत्तर

    4

    डिफ़ॉल्ट रूप से यह संभव नहीं है। प्रत्येक समाधान हमेशा सामग्री को वर्तमान दायरे में कॉपी करेगा, क्योंकि यदि नहीं, तो इसका उपयोग करने का कोई तरीका नहीं है।

    मुझे नहीं पता कि वास्तव में क्या करना है, लेकिन शायद आप इसे "बाहर" कर सकते हैं, उदाहरण के लिए gearman नौकरी के रूप में, और उसके बाद पूरी सरणी के बजाय प्रक्रिया के परिणाम पकड़ लें।

    आप स्लाइस में "बड़ी" सरणी को विभाजित करने के बारे में भी सोच सकते हैं और फिर उस हिस्से को हमेशा पुनर्प्राप्त कर सकते हैं जिसे आपको वर्तमान में एपीसी या मेमकैड से चाहिए।

    +5

    ठीक है, आखिरकार एक सहायक उत्तर: "संभव नहीं"। मैं अपमान या sarcasms की तुलना में ईमानदारी। धन्यवाद, यह मेरा स्वीकार्य उत्तर है। – Nuno

    +0

    आपके तीसरे पैराग्राफ के बारे में, मैं पहले से ही अन्य चीजों के लिए उस विधि का उपयोग करता हूं। मेरी चिंता यह है कि जब मैं वास्तव में नहीं जानता कि क्या हो रहा है, जैसा कि मैंने अपने प्रश्न में कहा था। – Nuno

    +2

    @ नूनो उस स्पर्शी मत बनो। किसी ने आपको अपमानित नहीं किया। यदि कोई उत्तर आपके लिए सहायक नहीं था, तो चोट लगने के बजाय अपने प्रश्न को बेहतर बनाने का प्रयास करें। –

    0

    संपादित करें:
    आप शायद साझा स्मृति गलत तरीके से उपयोग कर रहे हैं।
    आपकी साझा मेमोरी स्वयं ही ऐसी सरणी है। तो आपको अलग बहुभाषी तार सीधे साझा स्मृति में स्टोर करना होगा, उनके साथ बड़ी सरणी नहीं है।
    और फिर केवल विशेष पृष्ठ पर आवश्यक स्ट्रिंग खींचें।
    यह सब कुछ है।

    सामान्य रूप से, कुछ डेटा को संसाधित करने के लिए, किसी प्रोग्राम को इसे एक चर में संग्रहीत करके "डुप्लिकेट" करना होता है।
    कुछ बाहरी डेटा के लिए स्टोर (या "डुप्लिकेट") के लिए यह चर है।
    उदाहरण के लिए, यदि आपके पास अपने डेटाबेस में कुछ उपयोगकर्ता जानकारी है, तो वेब पेज पर उपयोगकर्ता नाम प्रदर्शित करने के लिए आपको इस डेटा को "डुप्लिकेट" करना होगा, इसे पहले PHP चर में संग्रहीत करना होगा।
    और इसी तरह।

    आप पहले सोचते हैं कि इस तरह के दृष्टिकोण को बदलने की जरूरत है।

    7

    PHP प्रक्रियाओं के बीच स्मृति साझा करने का एक तरीका है PHP-बाइटकोड कैश जैसे APC स्थापित करना। एपीसी का मुख्य रूप से बाइटकोड को ओएस प्रबंधित साझा-मेमोरी सेगमेंट में संग्रहीत करने के लिए उपयोग किया जाता है, लेकिन इसमें प्रक्रियाओं के बीच जो कुछ भी आप चाहते हैं उसे साझा करने के लिए एक एपीआई भी है (जैसे memcache के स्थानीय संस्करण)।

    <?php 
        $foobar = array('foo', 'bar'); 
        apc_store('foobar', $foobar); 
    ?> 
    

    तब कहीं:

    <?php 
        $foobar = apc_fetch('foobar'); 
        var_dump($foobar); 
    ?> 
    

    बंटवारे-स्मृति के साथ बड़ी समस्या यह है कि दो प्रक्रियाओं को एक दूसरे के पैर पर कदम रखने के लिए बहुत आसान हो जाता है। इसलिए साझा स्मृति उन चीज़ों के लिए सबसे अच्छी है जो बहुत अधिक नहीं बदलती हैं, जैसे बड़े वैश्विक सरणी।

    +0

    यह मेमकैच जैसा ही लगता है। आपके उत्तर के लिए धन्यवाद, वैसे भी :) – Nuno

    +1

    @NunoPeralta, 'Shmop' के बारे में क्या? निचे देखो। – Pacerier

    +0

    यह गलत है, apc_store आदि प्रक्रियाओं के बीच स्मृति साझा नहीं कर सकते हैं। प्रत्येक प्रक्रिया अपने स्वयं के मेमोरी सेगमेंट आवंटित करती है। आप इस कारण से php-fpm और php-cli के बीच स्मृति साझा नहीं कर सकते हैं (विभिन्न php-fpm अनुरोध कार्यों के बीच साझा करते समय)। – bhelm

    3

    पीएचपी जादू तरीकों है:

    • __get($property) हमें एक वस्तु पर एक $ संपत्ति की पहुँच को लागू
    • __set($property, $value) हमें एक वस्तु पर एक $ संपत्ति की नियुक्ति को लागू करने देते हैं

    PHP चर को क्रमबद्ध कर सकता है:

    • serialize($variable) रिटर्न चर
    • unserialize($string) रिटर्न की एक स्ट्रिंग प्रतिनिधित्व एक स्ट्रिंग से एक चर वापस

    पीएचपी समवर्ती का उपयोग प्रबंधन के साथ फ़ाइलें, संभाल कर सकते हैं:

    • fopen($file, 'c+') सलाहकार ताला विकल्पों के साथ एक फ़ाइल को खोलता है सक्षम (आपको झुंड का उपयोग करने की अनुमति देता है)
    • flock($descriptor, LOCK_SH) एक साझा लॉक लेता है (पढ़ने के लिए)
    • flock($descriptor, LOCK_EX) एक ई लेता है xclusive ताला (writting के लिए)

    तो, क्षुधा के बीच एक वस्तु साझा करने के लिए सबसे आसान तरीका है एक वर्ग है कि औजार और उन सभी सामान का उपयोग एक फ़ाइल में अपने सभी डेटा को बचाने और तुरंत बहाल करने के लिए तैयार करना है।

    उस वर्ग का एक सरल कार्यान्वयन हो सकता है:

    class Synchro 
    { 
    
        private $_file; 
    
        public function __construct($file) 
        { 
         $this->_file = $file; 
        } 
    
        public function __get($property) 
        { 
         // File does not exist 
         if (!is_file($this->_file)) 
         { 
          return null; 
         } 
    
         // Check if file is readable 
         if ((is_file($this->_file)) && (!is_readable($this->_file))) 
         { 
          throw new Exception(sprintf("File '%s' is not readable.", $this->_file)); 
         } 
    
         // Open file with advisory lock option enabled for reading and writting 
         if (($fd = fopen($this->_file, 'c+')) === false) 
         { 
          throw new Exception(sprintf("Can't open '%s' file.", $this->_file)); 
         } 
    
         // Request a lock for reading (hangs until lock is granted successfully) 
         if (flock($fd, LOCK_SH) === false) 
         { 
          throw new Exception(sprintf("Can't lock '%s' file for reading.", $this->_file)); 
         } 
    
         // A hand-made file_get_contents 
         $contents = ''; 
         while (($read = fread($fd, 32 * 1024)) !== '') 
         { 
          $contents .= $read; 
         } 
    
         // Release shared lock and close file 
         flock($fd, LOCK_UN); 
         fclose($fd); 
    
         // Restore shared data object and return requested property 
         $object = json_decode($contents); 
         if (property_exists($object, $property)) 
         { 
          return $object->{$property}; 
         } 
    
         return null; 
        } 
    
        public function __set($property, $value) 
        { 
         // Check if directory is writable if file does not exist 
         if ((!is_file($this->_file)) && (!is_writable(dirname($this->_file)))) 
         { 
          throw new Exception(sprintf("Directory '%s' does not exist or is not writable.", dirname($this->_file))); 
         } 
    
         // Check if file is writable if it exists 
         if ((is_file($this->_file)) && (!is_writable($this->_file))) 
         { 
          throw new Exception(sprintf("File '%s' is not writable.", $this->_file)); 
         } 
    
         // Open file with advisory lock option enabled for reading and writting 
         if (($fd = fopen($this->_file, 'c+')) === false) 
         { 
          throw new Exception(sprintf("Can't open '%s' file.", $this->_file)); 
         } 
    
         // Request a lock for writting (hangs until lock is granted successfully) 
         if (flock($fd, LOCK_EX) === false) 
         { 
          throw new Exception(sprintf("Can't lock '%s' file for writing.", $this->_file)); 
         } 
    
         // A hand-made file_get_contents 
         $contents = ''; 
         while (($read = fread($fd, 32 * 1024)) !== '') 
         { 
          $contents .= $read; 
         } 
    
         // Restore shared data object and set value for desired property 
         if (empty($contents)) 
         { 
          $object = new stdClass(); 
         } 
         else 
         { 
          $object = json_decode($contents); 
         } 
         $object->{$property} = $value; 
    
         // Go back at the beginning of file 
         rewind($fd); 
    
         // Truncate file 
         ftruncate($fd, strlen($contents)); 
    
         // Save shared data object to the file 
         fwrite($fd, json_encode($object)); 
    
         // Release exclusive lock and close file 
         flock($fd, LOCK_UN); 
         fclose($fd); 
    
         return $value; 
        } 
    
    } 
    

    अब, आप जब निर्माण stdClass की तरह इस वर्ग का उपयोग कर सकते हैं, लेकिन एक फ़ाइल पथ के साथ।

    $obj = new Synchro("/tmp/test.sync"); 
    $obj->hello = 'world'; 
    
    // ... and in another process... 
    echo $obj->hello; 
    

    यह उदाहरण, बहुत ही सरल निश्चित रूप से है कि यह एक फाइल करने के लिए समवर्ती पहुँच के बारे में है, लेकिन एक चर के लिए नहीं ख्याल रखता है, एक बेहतर कार्यान्वयन में आप एक म्युटेक्स की तरह ताला इस्तेमाल करेंगे।

    मैंने इस कक्षा को गिटूब पर (इसे पूरा करने के बाद) धक्का दिया, तो आप इसे here पा सकते हैं।

    +3

    आपने प्रश्न को गलत समझा है। – Pacerier

    +0

    इस तरह ... फ़ाइल का उपयोग करना सबसे आसान तरीका है, और अधिक सुरक्षित तरीका है, क्योंकि सर्वर की स्मृति का कोई प्रयास नहीं है। मुझे लगता है कि यह डेटाबेस भी पूछने से तेज है। – Meloman

    +0

    यह डेटाबेस का उपयोग करने से अलग नहीं है, विचार स्मृति में चर को साझा करना है, डिस्क पर नहीं। –

    18

    Shmop का उपयोग करना:

    Shmop कार्यों के सेट का उपयोग करने के लिए है कि PHP, पढ़ने के लिए लिखने, बनाने और हटाने यूनिक्स साझा स्मृति क्षेत्रों की अनुमति देता है एक आसान है।

    से: http://www.php.net/manual/en/intro.shmop.php

    कोई बाहरी पुस्तकालयों इस विस्तार का निर्माण करने की जरूरत है।

    साझा मेमोरी कार्य

    • shmop_close - बंद
    • साझा स्मृति ब्लॉक
    • shmop_delete - हटाएँ साझा स्मृति ब्लॉक
    • shmop_open - या खोलने साझा स्मृति ब्लॉक
    • shmop_read - साझा मेमोरी ब्लॉक से डेटा पढ़ें
    • ,210
    • shmop_size - साझा स्मृति ब्लॉक में डेटा लिखें

    बेसिक उपयोग

    // Create 100 byte shared memory block with system id of 0xff3 
    $shm_id = shmop_open(0xff3, "c", 0644, 100); 
    if (!$shm_id) { 
        echo "Couldn't create shared memory segment\n"; 
    } 
    
    // Get shared memory block's size 
    $shm_size = shmop_size($shm_id); 
    echo "SHM Block Size: " . $shm_size . " has been created.\n"; 
    
    // Lets write a test string into shared memory 
    $shm_bytes_written = shmop_write($shm_id, "my shared memory block", 0); 
    if ($shm_bytes_written != strlen("my shared memory block")) { 
        echo "Couldn't write the entire length of data\n"; 
    } 
    
    // Now lets read the string back 
    $my_string = shmop_read($shm_id, 0, $shm_size); 
    if (!$my_string) { 
        echo "Couldn't read from shared memory block\n"; 
    } 
    echo "The data inside shared memory was: " . $my_string . "\n"; 
    
    //Now lets delete the block and close the shared memory segment 
    if (!shmop_delete($shm_id)) { 
        echo "Couldn't mark shared memory block for deletion."; 
    } 
    shmop_close($shm_id); 
    
    +1

    यह भी देखें http://stackoverflow.com/a/8631902/632951 – Pacerier

    +1

    [shmop का उपयोग करने के लिए आपको अपनी कॉन्फ़िगरेशन लाइन में ** - enable-shmop ** पैरामीटर के साथ PHP को संकलित करने की आवश्यकता होगी।] (Http: // php.net/manual/en/shmop.installation.php) – Pang

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