PHP多进程同步下载图片的实现方法,pcntl_fork教程

 更新时间:2016年11月25日 16:19  点击:2101
pcntl_fork — 在当前进程当前位置产生分支(子进程)。译注:fork是创建了一个子进程,父进程和子进程 都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程 号,而子进程得到的是0。

pcntl_fork()函数创建一个子进程,这个子进程仅PID(进程号) 和PPID(父进程号)与其父进程不同。fork怎样在您的系统工作的详细信息请查阅您的系统 的fork(2)手册。

注意:PHP有个pcntl_fork的函数可以实现多进程,但要加载pcntl拓展,而且只有在linux下才能编译这个拓展.

1.首先在ubuntu下编译pcntl.so,我的ubuntu下找不到pcntl的包,于是创建一个文件夹下载了整个PHP包,在里面找到了pcntl包运行如下命令,代码如下:

 

 代码如下 复制代码
# mkdir php
# cd php
# apt-get source php5
# cd php5-(WHATEVER_RELEASE)/ext/pcntl
# phpize
# ./configure (注一)
# make
# make install phpize 命令是用来准备 PHP 外挂模块的编译环境的

 

成功的安装将建立 extname.so 并放置于 PHP 的外挂模块目录中(预设存放于 /usr/lib/php/modules/ 内),需要调整 php.ini,加入 extension=extname.so 这一行之后才能使用此外挂模块.

 代码如下 复制代码
void pcntl_exec(string $path [,array $args [,array $envs ]])

pcntl_exec — 在当前进程空间执行指定程序,代码如下:

$cmds=array(
        array('/home/jerry/projects/www/test2.php'),
        array('/home/jerry/projects/www/test3.php')
);
 
foreach($cmds as $cmd){
        $pid=pcntl_fork();
        if($pid==-1){
        //进程创建失败
            echo '创建子进程失败时返回-1';
            exit(-1);
        }
        else if($pid){
        //父进程会得到子进程号,所以这里是父进程执行的逻辑
            pcntl_wait($status,WNOHANG);
        }
        else{
        //子进程处理逻辑
            sleep(5);
            pcntl_exec('/usr/bin/php',$cmd);
            exit(0);
        }
}

 

例,实例多图片同步下载,代码如下:

 

 代码如下 复制代码
#!/usr/bin/php
<?php
// 需要抓取的网页地址
$url = 'http://www.jb51.net';
$content = file_get_contents($url);
preg_match_all('/<imgs+src="(.*?)"/', $content, $matches,PREG_SET_ORDER);
echo "已发现".count($matches)."张图片n";
 
list($sm, $ss) = explode(" ", microtime());
foreach ($matches as $k => $val)
{
 $pid[$k] = pcntl_fork();
 if(!$pid[$k])
 {
  download($url, $val);
  // 子进程要exit否则会进行递归多进程,父进程不要exit否则终止多进程
  exit(0);
 }
 
 if ($pid[$k])
 {
//    pcntl_waitpid($pid[$k], $status, WUNTRACED);
 }
 
}
echo "下载完成n";
 
list($em, $es) = explode(" ", microtime());
 
echo "用时:",($es+$em) - ($ss + $sm),"n";
/**
 * 抓取网页图片
 * 
 */
function download($url, $val)
{
 $pic_url = $val[1];
 if (strpos($val[1], '//') !== false)
 {
  ;
 }
 elseif (preg_match('@^(.*?)/@', $val[1], $inner_matches) == 0)
 {
  $pic_url = $url.$val[1];
 }
 elseif (preg_match('@[:.]@', $inner_matches[1], $tmp_matches) == 0)
 {
  $pic_url = $url.$val[1];
 }
 
 $pic = file_get_contents($pic_url);
 
 if ($pic === false)
 {
  return;
 }
 
 preg_match('@/([^/]+)$@', $pic_url, $tmp_matches);
 // 可使用assert处理异常
 $pic_file_name = $tmp_matches[1];
 $f = fopen("tmp/".$pic_file_name, "wb"); #
 fwrite($f, $pic);
 fclose($f);
}
 
/* End of file pcntl_fork.php */
?>

 

多进程同步下载图片是一个非常有用的技术,希望本教程对你有所帮助。

jQuery Mobile是jQuery 在手机上和平板设备上的版本。jQuery Mobile 不仅会给主流移动平台带来jQuery核心库,而且会发布一个完整统一的jQuery移动UI框架。现在我们来讲讲jQuery Mobile + php在手机上上传图片的实例。

很简单的一个小例子 jQuery Mobile + PHP 通过超全局 $_FILES 上传,然后用move_uploaded_file()方法把上传的图片移动到到本地服务器下的文件夹,

下面是html代码

 代码如下 复制代码
<!DOCTYPE html>
<html>
<head>
        <meta charset = "utf-8">
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css">
        <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
</head>
<body>
<div data-role="page" id="upload" >
       <div data-role="header"  >
                        <h1>校园祭</h1>
                        <a href="#pageone" data-rolr = button data-icon="home" class="ui-btn-left" >首页</a>
        </div>
        <div data-role="content" >
        <form action="upload_file.php" method="post" enctype="multipart/form-data" data-ajax="false">
                        <input  id="uploadimg" name="file"  type="file"  runat="server" method="post"
                                       enctype="multipart/form-data" data-inline="true"  data-ajax="false" />
                        <center><button  data-inline="true"  >上传</button></center>
        </form>
        </div>
        <div data-role="footer" data-position="fixed" data-fullscreen="true">
                        <h1>创新实验</h1>
        </div>
</div>
</body>
</html>


php的代码

 代码如下 复制代码
<?php
if ($_FILES["file"]["error"] > 0)
{
        echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{
       echo "Upload: " . $_FILES["file"]["name"] . "<br />";
        echo "Type: " . $_FILES["file"]["type"] . "<br />";
       echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
        echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
        if (file_exists("upload/" . $_FILES["file"]["name"]))
        {
                echo $_FILES["file"]["name"] . " already exists. ";
        }
        else
        {
                move_uploaded_file($_FILES["file"]["tmp_name"],
               "upload/".$_FILES["file"]["name"]);
                echo "Stored in: "  ."upload/". $_FILES["file"]["name"];
        }
}
}
?>


代码很简单,但是使用过程中却发现一个问题,自己试了好久都上传不了。询问了小伙伴后,发现问题所在是文件权限不足,从而限制了网页上传图片到文件夹中.所以解决办法就是把文件夹的权限问题解决掉.

 代码如下 复制代码
$ cd /var/www
$ sudo chmod -R  777  html


ok,现在就可以将文件上传到服务器的文件夹了.

下面来看一个关于php实现flash流媒体视频合成(F4M格式)的例子,希望例子可以帮助到各位朋友哦。

朋友发过来一个视频希望录制和下载下载,找了下工具借助此工具成功下载和合成;

去缓存拿到对应的流媒体的url地址,可以下载下来也可以通过url的方式进行合成;

推荐下载指定码率的 流媒体文件再进行合成,缓存中直接拿到的可能码率不同,合成的文件无法播放等,谨记.

项目地址:https://github.com/K-S-V/Scripts

本地下载:AdobeHDS.php And Scripts-master

Usage:

php AdobeHDS.php --manifest "your_manifest_url" --delete
MyVideo-Seg1-Frag1.f4f, MyVideo-Seg1-Frag2.f4f………MyVideo-Seg1-Frag99.f4f

php AdobeHDS.php MyVideo-Seg1-Frag
You can use script with following switches:

 --help              displays this help
 --debug             show debug output
 --delete            delete fragments after processing
 --fproxy            force proxy for downloading of fragments
 --play              dump stream to stdout for piping to media player
 --rename            rename fragments sequentially before processing
 --update            update the script to current git version
 --auth      [param] authentication string for fragment requests
 --duration  [param] stop recording after specified number of seconds
 --filesize  [param] split output file in chunks of specified size (MB)
 --fragments [param] base filename for fragments
 --manifest  [param] manifest file for downloading of fragments
 --outdir    [param] destination folder for output file
 --outfile   [param] filename to use for output file
 --parallel  [param] number of fragments to download simultaneously
 --proxy     [param] proxy for downloading of manifest
 --quality   [param] selected quality level (low|medium|high) or exact bitrate
 --referrer  [param] Referer to use for emulation of browser requests
 --start     [param] start from specified fragment
 --useragent [param] User-Agent to use for emulation of browser requests

由于php本身不支持多线程,如果我们想在php实现多线程是不是不可行呢?本教程来讲讲通过php的Socket方式实现php程序的多线程。

通过php的Socket方式实现php程序的多线程。php本身是不支持多线程的,那么如何在php中实现多线程呢?可以想一下,WEB服务器本身都是支持多线程的。每一个访问者,当访问WEB页面的时候,都将调用新的线程,通过这一点我们可以利用WEB服务器自身的线程来解决PHP不支持多线程的问题。

下面给出通过 fsockopen() 建立socket连接,然后用 用fputs() 发送消息,来实现的PHP多线程类代码:

 代码如下 复制代码
$fp=fsockopen($_SERVER['HTTP_HOST'],80,&$errno,&$errstr,5);
if(!$fp){
echo "$errstr ($errno)<br />n";
}
fputs($fp,"GET $_SERVER[PHP_SELF]?flag=1rn");
fclose($fp);


上面这段代码只是一个线程的操作过程。多进行几个这样的操作就是多线程了。目前所谓PHP的多线程程序都是基于这个方式的。

下面给一个完整的线程类代码。

 代码如下 复制代码
<?php
/**
@title:PHP多线程类(Thread)
@version:1.0
@author:axgle <axgle@126.com>
*/
class thread {
var $count;
function thread($count=1) {

$this->count=$count;
}

function _submit() {
for($i=1;$i<=$this->count;$i++) $this->_thread();
return true;
}


function _thread() {
$fp=fsockopen($_SERVER['HTTP_HOST'],80,&$errno,&$errstr,5);

if(!$fp){
echo "$errstr ($errno)<br />n";
}
fputs($fp,"GET $_SERVER[PHP_SELF]?flag=1rn");
fclose($fp);
}

function exec($func) {
isset($_GET['flag'])?call_user_func($func):$this->_submit();
}


}

//应用例子:
$th=new thread(10);//10个线程
$th->exec('demo');//执行行自定义的函数

function demo() {
fopen('data/'.microtime(),'w');
}

?>
PHP缓存的方法有很多种,常用的有memcache, memcached。现在我们来学习一个php缓存集成库phpFastCache,就是开源的,只有一个简单的php文件,就可以支持包括apc, memcache, memcached, wincache, files, pdo and mpdo等缓存方法。

phpFastCache是一个开源的PHP缓存库,只提供一个简单的PHP文件,可方便集成到已有项目,支持多种缓存方法,包括:apc, memcache, memcached, wincache, files, pdo and mpdo。可通过简单的API来定义缓存的有效时间。

 代码如下 复制代码
<?php
// In your config file
include("phpfastcache/phpfastcache.php");
phpFastCache::setup("storage","auto");

// phpFastCache support "apc", "memcache", "memcached", "wincache" ,"files", "sqlite" and "xcache"
// You don't need to change your code when you change your caching system. Or simple keep it auto
$cache = phpFastCache();

// In your Class, Functions, PHP Pages
// try to get from Cache first. product_page = YOUR Identity Keyword
$products = $cache->get("product_page");

if($products == null) {
    $products = YOUR DB QUERIES || GET_PRODUCTS_FUNCTION;
    // set products in to cache in 600 seconds = 10 minutes
    $cache->set("product_page", $products,600);
}

// Output Your Contents $products HERE



提高cURL和API调用性能

 代码如下 复制代码
<?php
include("phpfastcache/phpfastcache.php");

$cache = phpFastCache("memcached");

// try to get from Cache first.
$results = $cache->get("identity_keyword")

if($results == null) {
    $results = cURL->get("http://www.youtube.com/api/json/url/keyword/page");
    // Write to Cache Save API Calls next time
    $cache->set("identity_keyword", $results, 3600*24);
}

foreach($results as $video) {
    // Output Your Contents HERE
}



全页缓存

 代码如下 复制代码

<?php
// use Files Cache for Whole Page / Widget

// keyword = Webpage_URL
$keyword_webpage = md5($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
$html = __c("files")->get($keyword_webpage);

if($html == null) {
    ob_start();
    /*
        ALL OF YOUR CODE GO HERE
        RENDER YOUR PAGE, DB QUERY, WHATEVER
    */

    // GET HTML WEBPAGE
    $html = ob_get_contents();
    // Save to Cache 30 minutes
    __c("files")->set($keyword_webpage,$html, 1800);
}

echo $html;



挂件缓存

 代码如下 复制代码

<?php
// use Files Cache for Whole Page / Widget
$cache = phpFastCache("files");

$html = $cache->widget_1;

if($html == null) {
    $html = Render Your Page || Widget || "Hello World";
    // Save to Cache 30 minutes
    $cache->widget_1 = array($html, 1800);
}

echo or return your $html;



同时使用多种缓存

 代码如下 复制代码
<?php
// in your config files
include("phpfastcache/phpfastcache.php");
// auto | memcache | files ...etc. Will be default for $cache = __c();
phpFastCache::$storage = "auto";

$cache1 = phpFastCache();

$cache2 = __c("memcache");
$server = array(array("127.0.0.1",11211,100), array("128.5.1.3",11215,80));
$cache2->option("server", $server);

$cache3 = new phpFastCache("apc");

// How to Write?
$cache1->set("keyword1", "string|number|array|object", 300);
$cache2->keyword2 = array("something here", 600);
__c()->keyword3 = array("array|object", 3600*24);

// How to Read?
$data = $cache1->get("keyword1");
$data = $cache2->keyword2;
$data = __c()->keyword3;
$data = __c()->get("keyword4");

// Free to Travel between any caching methods

$cache1 = phpFastCache("files");
$cache1->set("keyword1", $value, $time);
$cache1->memcache->set("keyword1", $value, $time);
$cache1->apc->set("whatever", $value, 300);

$cache2 = __c("apc");
$cache2->keyword1 = array("so cool", 300);
$cache2->files->keyword1 = array("Oh yeah!", 600);

$data = __c("memcache")->get("keyword1");
$data = __c("files")->get("keyword2");
$data = __c()->keyword3;

// Multiple ? No Problem

$list = $cache1->getMulti(array("key1","key2","key3"));
$cache2->setMulti(array("key1","value1", 300),
                  array("key2","value2", 600),
                  array("key3","value3", 1800),
                  );

$list = $cache1->apc->getMulti(array("key1","key2","key3"));
__c()->memcache->getMulti(array("a","b","c"));

// want more? Check out document in source code
[!--infotagslink--]

相关文章

  • php抓取网站图片并保存的实现方法

    php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
  • mysql 批量更新与批量更新多条记录的不同值实现方法

    批量更新mysql更新语句很简单,更新一条数据的某个字段,一般这样写:复制代码 代码如下:UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value';如果更新同一字段为同一个值,mysql也很简单,修改下where即...2013-10-04
  • EXCEL数据上传到SQL SERVER中的简单实现方法

    EXCEL数据上传到SQL SERVER中的方法需要注意到三点!注意点一:要把EXCEL数据上传到SQL SERVER中必须提前把EXCEL传到服务器上.做法: 在ASP.NET环境中,添加一个FileUpload上传控件后台代码的E.X: 复制代码 代码如下: if...2013-09-23
  • 浅析c# 线程同步

    这篇文章主要介绍了c# 线程同步的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2020-08-29
  • MYSQL主从不同步延迟原理分析及解决方案

    1. MySQL数据库主从同步延迟原理。要说延时原理,得从mysql的数据库主从复制原理说起,mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日...2013-10-04
  • PHP翻页跳转功能实现方法

    我们都知道用php+mysql在web 页实现数据库资料全部显示是非常简单而有趣的,数据库资料很少的情况下页面显示还是让人满意的,但是当数据库资料非常多的情况下,页面的显示情况将会变的非常糟糕,下面就来介绍一下如何实现当...2015-11-08
  • 网页自动调用国内双核浏览器的极速模式的实现方法

    由于国内好几个浏览器都是双核浏览器(蛋痛,做一个浏览器壳就说国产,而且使用率高),有时打开网页会出现不兼容模式,在极速模式下是好的,现在我们来用代码实现网页自动调用国内...2016-09-20
  • C#同步网络时间的方法实例详解

    这篇文章主要介绍了C#同步网络时间的方法,以实例形式较为详细的分析了C#获取网络时间与同步本机系统时间的相关技巧,非常具有实用价值,需要的朋友可以参考下...2020-06-25
  • 检测mysql同步状态实现代码(php/linux)

    本文章介绍两个实例来介绍mysql同步状态检测实现程序有需要的朋友可参考一下。 代码如下 复制代码 #!/bin/sh #check MySQL_Slave St...2016-11-25
  • VSCode 云同步扩展设置Settings Sync插件

    这篇文章主要介绍了VSCode 云同步扩展设置Settings Sync插件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-29
  • MySQL 5.5主从同步设置笔记分享

    先修改Master(10.1.123.197)的 my.cnf 配置在 [mysqld] 中新增以下内容:复制代码 代码如下:log-bin=mysql-binlog-bin-index=mysql-bin.indexserver-id = 1sync_binlog=1binlog_format=mixed然后指定要做同步的数据库,并...2014-05-31
  • C#多线程及同步示例简析

    这篇文章主要为大家详细介绍了C#多线程及同步示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • PHP中对汉字进行unicode编码和解码的实现方法

    小编推荐的这篇文章介绍了PHP中对汉字进行unicode编码和解码的实现方法,非常实用,有兴趣的同学可以参考一下。 代码如下复制代码 //将内容进行UNICODE编码fu...2017-07-06
  • C#实现多线程的同步方法实例分析

    这篇文章主要介绍了C#实现多线程的同步方法,实例分析了C#线程同步的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • php安装pcntl扩展实现多进程

    pcntl中的php必须要安装pcntl才可以实现多线程了,在网上找到许多的关于pcntl安装教程,下面整理了一篇比较完整的关于php pcntl安装与使用方法。 pcntl中php实现多进...2016-11-25
  • vue data变量相互赋值后被实时同步的解决步骤

    这篇文章主要介绍了vue data变量相互赋值后被实时同步的解决步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-05
  • 基于C# 写一个 Redis 数据同步小工具

    Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这篇文章主要介绍了用 C# 写一个 Redis 数据同步小工具,需要的朋友可以参考下...2020-06-25
  • php 怎么跨域写cookie实现同步登陆代码

    //加上 代码如下 复制代码 header('p3p: cp="cura adma deva ps教程ao psdo our bus uni pur int dem sta pre com nav otc noi dsp cor"'); ...2016-11-25
  • 微信扫码网站自动登录的实现方法

    微信扫码网站自动登录的原是还是比较简单的,只要各位知道相互的原理就可以实现了,下面我们来看两个例子,我相信各位看了这两个例子肯定知道怎么来做了。 magento 微...2016-11-25
  • Oracle通过LogMiner实现数据同步迁移

    这篇文章主要介绍了Oracle通过LogMiner实现数据同步迁移的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-12-08