PHP pthreads v3 동기 화 처리 synchronized 용법 예시
6951 단어 PHPpthreads동기 처리synchronized
동기 화 를 사용 하 는 이 유 는 여러 스 레 드 에서 같은 자원 을 조작 할 때 혼란 이 발생 하기 때문이다.
예 를 들 어 두 개의 스 레 드 가 변 수 를 1 로 조작 하고 첫 번 째 스 레 드 가 아직 오지 않 았 을 때 두 번 째 스 레 드 는 변 수 를 조작 했다.그 변수의 최종 결 과 는 알 수 없 는 것 이 고 이 럴 때 동기 화 되 어 제어 해 야 한다.
예 는 다음 과 같다.
<?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}
";
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}
";
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}
";
}
}
$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 의 데 이 터 는 매번 1000000 을 증가 해 야 합 니 다.현재 의 컴퓨터 설정 이 모두 비교적 좋 으 니,모두 몇 번 더 실행 하면 효 과 를 볼 수 있다.마지막 데이터 가 20000 이 부족 한 것 같 습 니 다.다 중 스 레 드 에서 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}
";
}
}
$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 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
laravel에 yo에서 angularJs&coffeescript를 사용할 수 있도록 한다.먼저 yo 명령을 사용할 수 있어야하므로 아래에서 설치 global에 설치한 곳에서 laravel의 프로젝트 루트로 이동. 클라이언트 코드를 관리하는 디렉토리를 만들고 이동합니다. 클라이언트 환경 만들기 이것으로 히...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.