好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > PHP pthreads v3下同步處理synchronized用法示例

PHP pthreads v3下同步處理synchronized用法示例

熱門標簽:濟源百應電銷機器人聯系方式 南京3D地圖標注 嘟嘟云外呼系統 辦理400電話哪家好點 邢臺400電話辦理 正規電銷機器人系統 南寧電話外呼系統線路 重慶外呼電銷系統多少錢 咸陽電銷

本文實例講述了PHP pthreads v3下同步處理synchronized用法。分享給大家供大家參考,具體如下:

之所以會用到同步,是因為如果多個線程中對同一個資源進行操作時,會發生混亂。

比如2個線程對變量進行加1操作,第1個線程還沒來的及改寫數據時,第2個線程就對變量進行操作了,那變量最終的結果就是未知的,這個時候就需要同步來進行控制了。

例子如下:

?php
class Count extends Thread
{
  public $cnt = 0;

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

  public function add()
  {
    //對成員進行加1操作
    for ($i = 0; $i  100000; $i++) {
      ++$this->cnt;
    }
  }
}

$c = new Count();
//調用start()時,線程run()中就調用了add()方法
$c->start();
//我們人為再調用一次add()方法,這時候就會有兩個for循環對$cnt進行操作
$c->add();
//把創建的線程加入主線程中,讓主線程等待子線程運行結束
$c->join();

//這里輸出就是不確定性的
var_dump($c->cnt);

多次運行后,$cnt的值是不確定的。如下圖所示:

在pthreads v2中我們可以用Mutex,不過在v3版本中被刪除了,所以我們可以簡單的把加1操作放到synchronized中進行同步,代碼如下:

?php
class Count extends Thread
{
  public $cnt = 0;

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

  public function add()
  {
    $this->synchronized(function () {
      //對成員進行加1操作
      for ($i = 0; $i  100000; $i++) {
        ++$this->cnt;
      }
    });
  }
}

$c = new Count();
//調用start()時,線程run()中就調用了add()方法
$c->start();
//我們人為再調用一次add()方法,這時候就會有兩個for循環對$cnt進行操作
$c->add();
//把創建的線程加入主線程中,讓主線程等待子線程運行結束
$c->join();

//這里就會一直輸出200000
var_dump($c->cnt);

結果如下所示:

當然我們也可以通過notify()和wait()進行同步控制,代碼如下:

?php
class Task extends Thread
{
  public $flag = 1;

  public function run()
  {
    $this->synchronized(function () {
      //標識不為1就一直等待
      if ($this->flag !== 1) {
        $this->wait();
      }

      for ($i = 1; $i = 10; $i++) {

        echo "flag : {$this->flag} i : {$i} \n";

        if ($this->flag === 1) {
          //設置標識
          $this->flag = 2;
          //發送喚醒通知,然后讓當前線程等待
          //注意,notify()與wait()順序不要搞錯了,不然會一直阻塞
          $this->notify();
          $this->wait();
        }
      }

      //我們在這里再次調用notify()
      //因為在最后一次輸出flag : 2 i : 20時,當前線程的i已經變成11了,跳出了for循環,
      //但另一個線程則一直阻塞在wait()那里,程序無法結束,所以需要notify()再次喚醒一次
      $this->notify();
    });
  }
}

$t = new Task();
$t->start();

$t->synchronized(function ($obj) {
  //標識不為2就一直等待
  if ($obj->flag !== 2) {
    $obj->wait();
  }

  for ($i = 11; $i = 20; $i++) {

    echo "flag : {$obj->flag} i : {$i} \n";

    if ($obj->flag === 2) {
      $obj->flag = 1;
      $obj->notify();
      $obj->wait();
    }
  }
}, $t);

//把創建的線程加入主線程中,讓主線程等待子線程運行結束
$t->join();

結果如下圖所示:

我們通過notify()和wait()控制了兩個for循環,來回的輸出變量i的值,保證了順序性。

我們再來看一個復雜點的例子,共享的資源,如果不進行同步操作,會出現不可預知的情況,代碼如下: 

?php
class Task extends Thread
{
  private $name;
  private $file;

  public function __construct($name, $file)
  {
    $this->name = $name;
    $this->file = $file;
  }

  public function run()
  {
    $data = file_get_contents($this->file);
    $data = floatval($data);
    for ($i = 0; $i  100000; $i++) {
      ++$data;
    }
    file_put_contents($this->file, $data);
    echo "task : {$this->name} data : {$data} \n";
  }
}

$tasks = [];
$file = './test.log';

for ($i = 0; $i  100; $i++) {
  $tasks[$i] = new Task($i, $file);
  $tasks[$i]->start();
}

for ($i = 0; $i  100; $i++) {
  $tasks[$i]->join();
}

我們開100個線程對文件test.log進行讀寫,理想狀態下,test.log中的數據應該是每次增加10000000的。現在的電腦配置都比較好,大家可以多運行幾次就可以看出效果。

 很明顯最后的數據好像少了200000,多線程下對test.log文件進行讀寫,而我們又沒有加鎖,顯然是會出現數據混亂的。

現在我們修改一下代碼,如下:

?php
class File extends Thread
{
  private $file;

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

  public function inc()
  {
    //進行同步控制,當100個task線程調用inc方法時,synchronized可以保證塊內的代碼是同步的
    //注意,注意,不要把inc方法寫到Task里,那樣是沒效果的,因為每個task線程都是獨立空間,他們各自調各自的inc方法,是沒法做到同步的
    //常用的做法是我們要同步哪些資源,就為這些資源寫個Thread類,并提供操作這些資源的方法,并在方法里加上synchronized
    return $this->synchronized(function () {
      $data = file_get_contents($this->file);
      $data = floatval($data);
      for ($i = 0; $i  100000; $i++) {
        ++$data;
      }
      file_put_contents($this->file, $data);
      return $data;
    });
  }
}

class Task extends Thread
{
  private $name;
  private $file;

  public function __construct($name, $file)
  {
    $this->name = $name;
    $this->file = $file;
  }

  public function run()
  {
    $data = $this->file->inc();
    echo "task : {$this->name} data : {$data} \n";
  }
}

$tasks = [];
$file = new File('./test.log');

for ($i = 0; $i  100; $i++) {
  $tasks[$i] = new Task($i, $file);
  $tasks[$i]->start();
}

for ($i = 0; $i  100; $i++) {
  $tasks[$i]->join();
}

結果如下圖所示,當然為了保險起見,我們可以試著多運行幾次,下面是我運行了25次的結果:

更多關于PHP相關內容感興趣的讀者可查看本站專題:《PHP進程與線程操作技巧總結》、《PHP網絡編程技巧總結》、《PHP基本語法入門教程》、《PHP數組(Array)操作技巧大全》、《php字符串(string)用法總結》、《php+mysql數據庫操作入門教程》及《php常見數據庫操作技巧匯總》

希望本文所述對大家PHP程序設計有所幫助。

您可能感興趣的文章:
  • PHP pthread拓展使用和注意點
  • PHP pthreads v3下worker和pool的使用方法示例
  • PHP pthreads v3使用中的一些坑和注意點分析
  • php使用pthreads v3多線程實現抓取新浪新聞信息操作示例
  • PHP中使用pthread拓展

標簽:南通 河南 武漢 平頂山 黃山 隴南 通遼 唐山

巨人網絡通訊聲明:本文標題《PHP pthreads v3下同步處理synchronized用法示例》,本文關鍵詞  PHP,pthreads,下,同步,處理,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《PHP pthreads v3下同步處理synchronized用法示例》相關的同類信息!
  • 本頁收集關于PHP pthreads v3下同步處理synchronized用法示例的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 欧美毛多水多h日本一区二区 | 91成人在线| gl把她按在墙上嗦奶头gl| 涩涩色欲久久爱热99天堂夜夜| 25岁的女高中生未增删| 白嫩的极品女asspie| 国产欧美精品一区二区色欲91| 日久成瘾by是寒酥酥小说| 综合欧美日韩一区二区三区| 一区二区三区无码视频| 亚洲成a人片在线观看中文| 国产农村1级毛片| 亚洲国产三级| 欧美福利视频网站| 粗暴h疼哭np各种play网站| 长篇H香艳武侠小说| 美国大毛片| 91香蕉成人app无限观看| 人与野鲁?毛片免费浪女人| 亚洲精品久久无码77777| 日本三级理论全部电影| 他揉捏她两乳不停呻吟小说| 我扒开下面自慰给同桌看| 健身房被教练啪到腿软H漫画 | 大胸奶头晃着喷奶水H漫画小说 | 好爽要尿了潮喷了的视频| 无遮挡h肉动漫在线观| 高h辣文短篇辣文| 女朋友太骚了每次进去都觉得很疼| 成人精品一区日本无码网站suv | 在线AV免费无码一区| 欧美金妇乱妇熟妇XXXX生| 亚洲精品无码一区二区aⅴ| 欧美人与zoxⅹxx另类视频| 美女私密照不遮挡| 班长张开腿让我?了一节课动图| 优优色在线影院亚洲| 中文日本在线| 日本无遮挡大乳吃胸视频| 大尺度床戏亲胸吃奶| 被粗大灌满了白浆|