PHP는 locking_php 예제를 통해 동시성에서 코드 캡처 기능을 실현합니다.

WBOY
풀어 주다: 2016-08-17 13:02:34
원래의
972명이 탐색했습니다.

요구사항: 코드 캡쳐 기능

요구사항:

1. 코드 잡기는 특정 기간에만 가능합니다.

2. 각 기간별로 출시되는 코드는 제한되어 있습니다.

3. 각 코드는 반복될 수 없습니다.

구현:

1. 동시성을 고려하지 않고 구현:

function get_code($len){
$CHAR_ARR = array('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','X','Y','Z','W','S','R','T');
$CHAR_ARR_LEN = count($CHAR_ARR) - 1;
$code = '';
while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; }
return $code;
}
$pdo = new PDO('mysql:host=localhost;dbname=ci_test','root','root');
//查询当前时间已发放验证码数量
$code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test");
$code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC);
$code_num = $code_num_arr['sum'];
if($code_num < 1){<br>   sleep(2); //暂停2秒
$code = get_code(6);
var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES ('$code',".time().")") );
} 
로그인 후 복사

위 코드는 기본적으로 현재 영업시간을 만족하며, 코드가 반복되지 않습니다.

동시성을 고려하지 않은 프로세스:

1) 현재 데이터베이스에서 발급된 인증 코드 개수를 쿼리하려면 선택하세요.

2) 아직 장소가 있는 경우 인증 코드를 생성하여 데이터베이스에 삽입한 후 클라이언트에 인증 코드를 반환합니다.

3) 가득 차면 더 이상 장소가 없다는 메시지가 반환됩니다.

2. 동시 조건에 따른 구현:

그런 다음 동시 상황에서 위 코드로 얻은 결과를 살펴보세요.

동시성을 테스트하려면 apache 벤치마크를 사용하여 테스트할 수 있습니다. apache 벤치마크는 APACHE 아래의 HTTP SERVER에 대한 성능 평가 도구입니다. cmd를 통해 apche의 bin 디렉터리를 입력하고 ab -c와 같은 명령을 통해 호출합니다. 동시수 -n 총 방문수 url

코드 복사 코드는 다음과 같습니다.

cb -c 100 -n 100 http://localhost/php_mulit.php

이런 식으로 100명의 사용자와 동료가 1개의 할당량을 얻으려고 합니다. 쿼리할 때 각 사용자가 아직 할당량이 있음을 발견하면 인증 코드가 생성되어 데이터베이스에 삽입되고 인증 코드는 다음과 같습니다. 반환되어 인증이 발생했습니다. 코드가 너무 많이 발급되었습니다. 실제로 이 명령을 실행한 후 데이터베이스에는 1개가 아닌 13개의 레코드가 더 포함됩니다.

이런 일이 발생하지 않도록 하려면 어떻게 해야 하나요?

이 판단 과정에서 언제든지 하나의 프로세스만 실행되도록 배타적 잠금을 추가하여 판단부터 삽입까지 프로세스를 잠글 수 있습니다. 구현은 다음과 같습니다.

//生成码
function get_code($len){
$CHAR_ARR = array('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','X','Y','Z','W','S','R','T');
$CHAR_ARR_LEN = count($CHAR_ARR) - 1;
$code = '';
while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; }
return $code;
}
$pdo = new PDO('mysql:host=localhost;dbname=ci_test','root','root');
$fp = fopen('lock.txt','r');
//通过排他锁 锁定该过程
if(flock($fp,LOCK_EX)){
//查询当前时间已发放验证码数量
$code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test");
$code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC);
$code_num = $code_num_arr['sum'];
if($code_num < 1){
sleep(2);
$code = get_code(6);
var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES ('$code',".time().")") );
}
flock($fp,LOCK_UN);
fclose($fp);
} 
로그인 후 복사

플록 기능을 통해 프로세스를 잠급니다.

더 많은 무리 정보를 보려면 PHP 매뉴얼을 참조하세요: http://php.net/manual/zh/function.flock.php

다시 실행

코드 복사 코드는 다음과 같습니다.

cb -c 100 -n 100 http://localhost/php_mulit.php

동시 조건에서 데이터의 정확성을 보장하기 위해 하나의 레코드만 데이터베이스에 추가됩니다.

위 내용은 잠금을 통한 동시성 PHP 코드 캡처 기능에 대한 편집자의 소개입니다. 궁금한 점이 있으면 메시지를 남겨주시면 편집자가 시간에 맞춰 답변해 드리겠습니다. 또한 Script House 웹사이트를 지원해 주시는 모든 분들께 감사의 말씀을 전하고 싶습니다!

관련 라벨:
php
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿