2014-08-27 68 views
2

我在同一時間運行2個線程,但是我有關鍵部分,我需要將某些內容放入MySql數據庫中。問題是他們可以同時放置同樣的東西。同步和暫停PHP中的線程

我已經做了一些計算方法,顯示索引20000個不同的新聞網頁,索引是從20000到20020.(所以0〜20是重複的)

如何暫停一個線程,而另一個是訪問數據庫?

-----thread.php 
class Process extends Thread { 

    public function __construct($website_url){ 
     $this->website_url = $website_url; 
    } 

    public function run() { 
     work($this->website_url); 
    } 
} 

-------------- work 

function work($website_url) { 
    while(condition) { 
     some work... 

     if(something->check){  // if this exist in base 
      mysqli->query("INSERT something IN db..."); 
      prepare bind exec... 
     } 
     // between check and insert, second thread can put that element 
     // critical section is really small but sometimes occurs ... 
    } 
} 

------ main.php 

$job1 = new Process($website_url,$trigger); 
$job2 = new Process($website_url,$trigger); 

$job1->start(); 
$job2->start(); 
+0

MyISAM或InnoDB?鎖定你正在寫的表,問題解決.. – Ohgodwhy 2014-08-27 17:59:14

+0

@Ohgodwhy InnoDB,但問題是在PHP中,我檢查,並格式化有關新聞的信息,然後我打電話插入查詢。 – 2014-08-27 18:02:12

+1

首先運行一個'SHOW OPEN TABLES'查詢,迭代結果,檢測有問題的表,如果存在則不運行查詢,如果不存在,則運行查詢 – Ohgodwhy 2014-08-27 18:03:27

回答

5

互斥

實現的最簡單的方法你想要的這裏是通過使用單一互斥的:

<?php 
class Process extends Thread { 

    public function __construct($url, $mutex) { 
     $this->url = $url; 
     $this->mutex = $mutex; 
    } 

    public function run() { 
     work($this->url, $this->mutex); 
    } 

    protected $url; 
    protected $mutex; 
} 

function work($url, $mutex) { 
    while (1) { 
     /* some work */ 

     /* failing to check the return value of calls to acquire 
      or release mutex is bad form, I haven't done so for brevity */ 
     Mutex::lock($mutex); 
     { 
      /* critical section */ 
      printf("working on %s\n", $url); 

      /* sleeping here shows you that the critical section is 
       not entered by the second thread, this is obviously not needed */ 
      sleep(1); 
     } 
     Mutex::unlock($mutex); 

     /* breaking here allows the example code to end, not needed */ 
     break; 
    } 
} 

$website = "stackoverflow.com"; 

$lock = Mutex::create(); 

$jobs = [ 
    new Process($website, $lock), 
    new Process($website, $lock) 
]; 

foreach ($jobs as $job) 
    $job->start(); 

foreach ($jobs as $job) 
    $job->join(); 

/* always destroy mutex when finished with them */  
Mutex::destroy($lock); 
?> 

此代碼應該解釋本身,我增加了一些註解引導你完成它。