精华内容
下载资源
问答
  • 城市商业空间的合理布局,有利于优化城市内部空间商业资源的配置。 基于绵阳中部地区的商业POI(Point of Interest)数据,利用核密度估计,Getis-Ord,Ripley的K函数和位置熵方法,并利用绵密度分析了不同尺度下...
  • Linux高级配置详解

    2011-06-11 06:59:29
    本书共由6章组成,‘简要地介绍了Linux系统的功能特点和需求,阐述了Linux的起源、成长过程以及未来发展方向。在软件配置方面,介绍了在Linux下软件的两种安装方式(源代码和RPM)、常用软件Oracle、Sybasease和...
  • 一般而言,Sphinx是一个独立搜索引擎,意图为其他应用提供高速、低空间占用、高结果相关度全文搜索功能。Sphinx可以非常容易与SQL数据库和脚本语言集成。 当前系统内置MySQL和PostgreSQL...

    一、关于Sphinx

    Sphinx 是一个在GPLv2 下发布的一个全文检索引擎,商业授权(例如, 嵌入到其他程序中)需要联系作者(Sphinxsearch.com)以获得商业授权。

    一般而言,Sphinx是一个独立的搜索引擎,意图为其他应用提供高速、低空间占用、高结果相关度的全文搜索功能。Sphinx可以非常容易的与SQL数据库和脚本语言集成。

    当前系统内置MySQL和PostgreSQL 数据库数据源的支持,也支持从标准输入读取特定格式的XML数据。通过修改源代码,用户可以自行增加新的数据源(例如:其他类型的DBMS的原生支持)。

    搜索API支持PHP、Python、Perl、Rudy和Java,并且也可以用作MySQL存储引擎。搜索API非常简单,可以在若干个小时之内移植到新的语言上。

    Sphinx特性:

    • 高速的建立索引(在当代CPU上,峰值性能可达到10MB/秒);
    • 高性能的搜索(在2–4GB的文本数据上,平均每次检索响应时间小于0.1秒);
    • 可处理海量数据(目前已知可以处理超过100GB的文本数据,在单一CPU的系统上可处理100M文档);
    • 提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法;
    • 支持分布式搜索;
    • 提供文件的摘录生成;
    • 可作为MySQL的存储引擎提供搜索服务;
    • 支持布尔、短语、词语相似度等多种检索模式;
    • 文档支持多个全文检索字段(最大不超过32个);
    • 文档支持多个额外的属性信息(例如:分组信息,时间戳等);
    • 停止词查询;
    • 支持单一字节编码和UTF-8编码;
    • 原生的MySQL支持(同时支持MyISAM和InnoDB);
    • 原生的PostgreSQL支持.

    中文手册可以在这里获得,感谢译者的辛勤工作。

    二、Sphinx在windows上的安装

    1.直接在http://www.sphinxsearch.com/downloads.html找到最新的windows版本,我这里下的是Win32 release binaries with MySQL support,下载后解压在D:\sphinx目录下;

    2.在D:\sphinx\下新建一个data目录用来存放索引文件,一个log目录方日志文件,复制D:\sphinx\sphinx.conf.in到D:\sphinx\bin\sphinx.conf(注意修改文件名);

    3.修改D:\sphinx\bin\sphinx.conf,我这里列出需要修改的几个:

    type        = mysql # 数据源,我这里是mysql
    sql_host    = localhost # 数据库服务器
    sql_user    = root # 数据库用户名
    sql_pass    = '' # 数据库密码
    sql_db      = test # 数据库
    sql_port    = 3306 # 数据库端口
    sql_query_pre   = SET NAMES utf8 # 去掉此行前面的注释,如果你的数据库是uft8编码的
    index test1
    {
    # 放索引的目录
     path   = D:/sphinx/data/
    # 编码
     charset_type  = utf-8
     #  指定utf-8的编码表
     charset_table  = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
     # 简单分词,只支持0和1,如果要搜索中文,请指定为1
     ngram_len    = 1
    # 需要分词的字符,如果要搜索中文,去掉前面的注释
     ngram_chars   = U+3000..U+2FA1F
    }
    # index test1stemmed : test1
    # {
     # path   = @CONFDIR@/data/test1stemmed
     # morphology  = stem_en
    # }

     

    # 如果没有分布式索引,注释掉下面的内容

    # index dist1
    # {
     # 'distributed' index type MUST be specified
     # type    = distributed

     # local index to be searched
     # there can be many local indexes configured
     # local    = test1
     # local    = test1stemmed
     # remote agent
     # multiple remote agents may be specified
     # syntax is 'hostname:port:index1,[index2[,...]]
     # agent    = localhost:3313:remote1
     # agent    = localhost:3314:remote2,remote3
     # remote agent connection timeout, milliseconds
     # optional, default is 1000 ms, ie. 1 sec
     # agent_connect_timeout = 1000
     # remote agent query timeout, milliseconds
     # optional, default is 3000 ms, ie. 3 sec
     # agent_query_timeout  = 3000
    # }
    # 搜索服务需要修改的部分
    searchd
    {
     # 日志
     log     = D:/sphinx/log/searchd.log
     # PID file, searchd process ID file name
     pid_file   = D:/sphinx/log/searchd.pid
     # windows下启动searchd服务一定要注释掉这个
    # seamless_rotate  = 1
    }

    4.导入测试数据

    C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uroot test<d:/sphinx/example.sql

    5.建立索引

    D:\sphinx\bin>indexer.exe –all
    Sphinx 0.9.8-release (r1533)
    Copyright (c) 2001-2008, Andrew Aksyonoff

    using config file ‘./sphinx.conf’…
    indexing index ‘test1′…
    collected 4 docs, 0.0 MB
    sorted 0.0 Mhits, 100.0% done
    total 4 docs, 193 bytes
    total 0.101 sec, 1916.30 bytes/sec, 39.72 docs/sec

    D:\sphinx\bin>

    6.搜索’test’试试

    D:\sphinx\bin>search.exe test
    Sphinx 0.9.8-release (r1533)
    Copyright (c) 2001-2008, Andrew Aksyonoff

    using config file ‘./sphinx.conf’…
    index ‘test1′: query ‘test ‘: returned 3 matches of 3 total in 0.000 sec

    displaying matches:
    1. document=1, weight=2, group_id=1, date_added=Wed Nov 26 14:58:59 2008
            id=1
            group_id=1
            group_id2=5
            date_added=2008-11-26 14:58:59
            title=test one
            content=this is my test document number one. also checking search within
     phrases.
    2. document=2, weight=2, group_id=1, date_added=Wed Nov 26 14:58:59 2008
            id=2
            group_id=1
            group_id2=6
            date_added=2008-11-26 14:58:59
            title=test two
            content=this is my test document number two
    3. document=4, weight=1, group_id=2, date_added=Wed Nov 26 14:58:59 2008
            id=4
            group_id=2
            group_id2=8
            date_added=2008-11-26 14:58:59
            title=doc number four
            content=this is to test groups

    words:
    1. ‘test’: 3 documents, 5 hits
    D:\sphinx\bin>

    都所出来了吧。

    6.测试中文搜索

    修改test数据库中documents数据表,

    UPDATE `test`.`documents` SET `title` = ‘测试中文’, `content` = ‘this is my test document number two,应该搜的到吧’ WHERE `documents`.`id` = 2;

    重建索引:

    D:\sphinx\bin>indexer.exe –all

    搜索’中文’试试:

    D:\sphinx\bin>search.exe 中文
    Sphinx 0.9.8-release (r1533)
    Copyright (c) 2001-2008, Andrew Aksyonoff

    using config file ‘./sphinx.conf’…
    index ‘test1′: query ‘中文 ‘: returned 0 matches of 0 total in 0.000 sec

    words:
    D:\sphinx\bin>

    貌似没有搜到,这是因为windows命令行中的编码是gbk,当然搜不出来。我们可以用程序试试,在D:\sphinx\api下新建一个foo.php的文件,注意utf-8编码

    <?php
    require ‘sphinxapi.php’;
    $s = new SphinxClient();
    $s->SetServer(‘localhost’,3312);
    $result = $s->Query(‘中文’);
    var_dump($result);
    ?>

    启动Sphinx searchd服务

    D:\sphinx\bin>searchd.exe
    Sphinx 0.9.8-release (r1533)
    Copyright (c) 2001-2008, Andrew Aksyonoff

    WARNING: forcing –console mode on Windows
    using config file ‘./sphinx.conf’…
    creating server socket on 0.0.0.0:3312
    accepting connections

    执行PHP查询:

    php d:/sphinx/api/foo.php

    使用 CORESEEK 分词

    1 、下载 http://www.coreseek.cn/news/5/89/

    2 、安装系统依赖的软件包

    系统的基础组件需要如下的软件包:

       - Active Python 2.5 ( http://www.activestate.com/Products/activepython/ )
       - MySQL_Python 1.2.2 (http://sourceforge.net/project/showfiles.php?group_id=22307 
     验证 可以不装

    安装完前面两个组件后,系统可以运行,但是需要手工修改配置文件。

    安装配置界面需要的软件包:

    - gtk-dev 2.12.9 (http://sourceforge.net/project/showfiles.php?group_id=98754 验证可以不装 
        - pycairo 1.4.12 (http://ftp.acc.umu.se/pub/GNOME/binaries/win32/pycairo/1.4/ ) 
        - pygobject 2.14.1 (http://ftp.acc.umu.se/pub/GNOME/binaries/win32/pygobject/2.14/ ) 
        - pygtk 2.12.1 (http://ftp.acc.umu.se/pub/GNOME/binaries/win32/pygtk/2.12 ) )

    如果您下载的是完整版,前面提到的全部文件应该能在preq 子目录中找到。
    安装前面提到的全部软件包(注意:必须先安装Python 和gtk)

    注意必须是Active Python ,Python 官方的版本缺少系统需要的Win32 扩展支持,将导致系统无法工作。

    注意: 完成本步后,必须重新启动您的计算机。

    3 、解压 csft 到你认为的目录

    4 、csft 文件内配与 sphinx 的内容大致相同 ( 配置详细见:sphinx+mysql (1) , (2) )

    5 、创建词典文件

    /bin/mmseg -u /data/unigram.txt    # 词库是动态的,指定目录就可以

    ·   把生成的文件改名为uni.lib ,

    6 、导入sample.sql 数据库

    7 、建立索引 index.exe --all   (详情见 sphinx + mysql(1) )

    以下分支说明如下

    ---------------------------------------------------------------

    A 

    8 、安装SPHINXSE FOR MYSQL

    http://www.sphinxsearch.com/downloads/mysql-5.0.45-sphinxse-0.9.8-win32.zip

    下载后,解压然后覆盖MYSQL 目录,就OK 。 ( 注意mysql 版本 必须相同)

    进入mysql 运行 show engines; 查看表的类型是否存在 sphinx

    9 、创建Sphinx 存储引擎表
    CREATE TABLE `sphinx` (
    `id` int(11) NOT NULL,
    `weight` int(11) NOT NULL,
    `query` varchar(255) NOT NULL,
    `group_id` int(11) NOT NULL,
    KEY `Query` (`Query`)
    ) ENGINE=SPHINX CONNECTION='sphinx://localhost:3312/test1';

    与一般mysql 表不同的是ENGINE=SPHINX CONNECTION='sphinx://localhost:3312/test1'; ,这里表示这个表采用SPHINXSE 引擎,与sphinx 的连接串是'sphinx://localhost:3312/test1 ,test1 是索引名称
    根据sphinx 官方说明,这个表必须至少有三个字段,字段起什么名称无所谓,但类型的顺序必须是integer,integer,varchar ,分别表示记录标识document ID, 匹配权重weight 与查询query ,同时document IDquery 必须建索引。另外这个表还可以建立几个字段,这几个字段的只能是integer 或TIMESTAMP 类型,字段是与sphinx 的结果集绑定的,因此字段的名称必须与在sphinx.conf 中定义的属性名称一致,否则取出来的将是Null 值。

    10 、MySQL SphinxSE 全文检索存储引擎SQL 语句使用方法

    安装SphinxSE 存储引擎后首先需新建一张特殊的指定"ENGINE=SPHINX" 检索表,如下:

    CREATE TABLE ArticleFulltext (
        ID          INTEGER NOT NULL,
        Weight      INTEGER NOT NULL,
        Query      VARCHAR(3072) NOT NULL,
        ...
        INDEX (Query)
    ) ENGINE=SPHINX CONNECTION="sphinx://localhost:3312/test";

    ·   其中表名和字段名可以是任意名称,但前三个属性的类型必须为INT 、INT 和VARCHAR 。也可以拥有更多的属性,类型必须为INT 或TIMESTAMP ,名称必须与Sphinx 配置文件对应,用于返回检索结果的更多信息。

    ·   创建该表后即可使用如下的SQL 语句在MySQL 中进行全文检索:

    ·   SELECT * FROM ArticleFulltext WHERE Query=' 全文检索条件';

    ·   查询返回结果即为全文检索的结果,包括文档ID 、权重,若ArticleFulltext 表包含了更多属性还包含命中结果的其它信息。

    ·   通过SQL 联接操作可以很容易的实现融合检索,如:

    ·   SELECT ID, Title 
    FROM Article, ArticleFulltext
    WHERE ArticleFulltext.ID = Article.ID and Query = '
     博客
    AND PublishTime > '2007-03-01' AND ReferCount > 0
    ORDER BY Weight * 0.5 + ReferCount * 0.5;

    ·   上述SQL 语句即可检索出2007 年3 月1 日以来包含' 博客' 关键字且并引用过的文章,且按全文检索权重和引用数综合计算所得的权重进行排序。

    ·   由此可见,通过将全文检索系统提供的功能以存储引擎的形式嵌入到关系数据库MySQL 中可以很方便的提供融合检索功能,虽然功能限制较多,也不失为一种聪明便捷的方式。

    11, 将SPHINX 生成WINDOWS 服务

    searchd --install --config "csft.conf"

    12. 启动服务 net start |searchd( 或者其它服务名)

    ---------------------------------------------------------------

    B 

    配置sphinx.conf 文件,支持中文编码


    charset_type = zh_cn.utf-8 
    charset_dictpath = D:/csft3.1/bin   # 
    分词 lib 库文件的目录 

    min_infix_len = 0

    转载于:https://www.cnblogs.com/j-king/p/3641556.html

    展开全文
  • 声明本教程不得用于任何形式的商业用途,如果需要转载请与作者SCP-173联系,如果发现...另一方面,Linux系统下对显卡支持、内存释放以及存储空间调整等硬件功能支持较好。如果您对Linux环境感到陌生,并且大多数开发...

    声明

    本教程不得用于任何形式的商业用途,如果需要转载请与作者SCP-173联系,如果发现未经允许复制转载,将保留追求其法律责任的权利。

    这里需要说明一下,笔者不建议在Windows环境下进行深度学习的研究,一方面是因为Windows所对应的框架搭建的依赖过多,社区设定不完全;另一方面,Linux系统下对显卡支持、内存释放以及存储空间调整等硬件功能支持较好。如果您对Linux环境感到陌生,并且大多数开发环境在Windows下更方便操作的话,希望这篇文章对您会有帮助。

    关于计算机的硬件配置说明

    推荐配置

    如果您是高校学生或者高级研究人员,并且实验室或者个人资金充沛,建议您采用如下配置:主板:X99型号或Z170型号

    CPU: i7-5830K或i7-6700K 及其以上高级型号

    内存:品牌内存,总容量32G以上,根据主板组成4通道或8通道

    SSD: 品牌固态硬盘,容量256G以上

    显卡:NVIDIA GTX 1080、NVIDIA GTX TITAN、NVIDIA GTX 1070、NVIDIA GTX 1060 (顺序为优先建议,并且建议同一显卡,可以根据主板插槽数量购买多块,例如X99型号主板最多可以采用×4的显卡)

    电源:由主机机容量的确定,一般有显卡总容量后再加200W即可

    最低配置

    如果您是仅仅用于自学或代码调试,亦或是条件所限仅采用自己现有的设备进行开发,那么您的电脑至少满足以下几点:CPU:Intel第三代i5和i7以上系列产品或同性能AMD公司产品

    内存:总容量4G以上

    CPU说明大多数CPU目前支持多核多线程,那么如果您采用CPU加速,就可以使用多线程运算。这方面的优势对于服务器CPU集群和多核并行CPU尤为关键

    显卡说明如果您的显卡是非NVIDIA公司的产品或是NVIDIA GTX系列中型号的第一个数字低于4或NVIDIA的GT系列,都不建议您采用此类显卡进行加速计算,例如NVIDIA GT 910、NVIDIA GTX 450 等等。

    如果您的显卡为笔记本上的GTX移动显卡(型号后面带有标识M),那么请您慎重使用显卡加速,因为移动版GPU很容易发生过热烧毁现象。

    如果您的显卡,显示的是诸如 HD5000,ATI 5650 等类型的显卡,那么您只能使用CPU加速

    如果您的显卡为Pascal架构的显卡(NVIDIA GTX 1080,NVIDIA GTX 1070等),您只能在之后的配置中选择Visual Studio 2015和CUDA 8.0

    基本开发环境搭建

    1. Microsoft Windows 版本

    关于Windows的版本选择,本人强烈建议对于部分高性能的新机器采用Windows 10作为基础环境,部分老旧笔记本或低性能机器采用Windows 7即可,本文环境将以Windows 10作为开发环境进行描述。对于Windows 10的发行版本选择,笔者建议采用Windows_10_enterprise_2016_ltsb_x64作为基础环境。

    这里推荐到MSDN我告诉你下载,也感谢作者国内优秀作者雪龙狼前辈所做出的贡献。

    直接贴出热链,复制粘贴迅雷下载:

    ed2k://|file|cn_windows_10_enterprise_2016_ltsb_x64_dvd_9060409.iso|3821895680|FF17FF2D5919E3A560151BBC11C399D1|/

    2. 编译环境Microsoft Visual Studio 2010 - 2015

    (安装CPU版本非必须安装)

    CUDA编译器为Microsoft Visual Studio,版本从2010-2015,其中cuda7.5仅支持2010、2012、2013,cuda8.0仅支持2015版本,本文采用Visual Studio 2015 Update 3。同样直接贴出迅雷热链:

    ed2k://|file|cn_visual_studio_professional_2015_with_update_3_x86_x64_dvd_8923256.iso|7745202176|DD35D3D169D553224BE5FB44E074ED5E|/

    3. Python环境

    python环境建设推荐使用科学计算集成python发行版Anaconda,Anaconda是Python众多发行版中非常适用于科学计算的版本,里面已经集成了很多优秀的科学计算Python库。对于搞科学计算与深度学习的朋友们,建议安装Anconda2.7版本,如果您喜欢使用Anaconda3.5版本也没有太大问题,关于很多早期的python3.5不兼容问题现在已经全部解决,本文默认使用Anaconda2.7

    4. GCC编译环境

    gcc/g++是Windows环境与Linux环境非常大的一个差别点。不管是cpu版本还是gpu版本都需要安装GCC编译环境。本文提供两种解决方案:MinGW Minimalist GNU for Windows,安装好Anaconda之后在CMD或者Powershell中输入:

    conda install mingw libpythonMSYS2 一部分读者自己本身已经具有了Python环境,再安装Anaconda会造成很大的不便,那么本文推荐安装MSYS2,网站上有详细的如何安装的说明,本文不再赘述。

    5. CUDA

    (仅使用CPU版本不必安装)CUDA Toolkit是NVIDIA公司面向GPU编程提供的基础工具包,也是驱动显卡计算的核心技术工具。直接安装CUDA8.0即可下载地址:https://developer.nvidia.com/cuda-downloads

    在下载之后,按照步骤安装,不建议新手修改安装目录,同上,环境不需要配置,安装程序会自动配置好。

    6. (可选)加速库CuDNN

    从官网下载需要注册账号申请,两三天批准。网盘搜索一般也能找到最新版。 Windows目前就是cudnn-7.0-win-x64-v5.0-prod.zip。 下载解压出来是名为cuda的文件夹,里面有bin、include、lib,将三个文件夹复制到安装CUDA的地方覆盖对应文件夹,默认文件夹在:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA

    Keras 框架搭建

    安装

    Keras深度学习框架是基于Theano或Tensorflow框架安装的,所以首先要准备底层框架的搭建,然而目前Tensorflow不支持Windows版本,所以本文选用Theano安装即可在CMD命令行或者Powershell中输入:

    pip install theano -U --prepip install keras -U --pre

    或者想要加速开发版本,用(前提是已经git, conda install git)

    pip install --upgrade --no-deps git+git://github.com/Theano/Theano.git

    环境配置

    在我的电脑上右键->属性->高级->环境变量->系统变量中的path,添加

    C:\Anaconda2;C:\Anaconda2\Scripts;C:\Anaconda2\MinGW\bin;C:\Anaconda2\MinGW\x86_64-w64-mingw32\lib;

    注意,本文将Anaconda安装至C盘根目录,根据自己的情况进行修改;另外在之前安装gcc/g++时采用MSYS2方式安装的,修改并重新定位MinGW文件夹,并做相应修改。

    之后并新建变量PYTHONPATH,并添加

    C:\Anaconda2\Lib\site-packages\theano;修改默认后端

    打开C:\Users\当前用户名\.keras,修改文件夹内的keras.json文件如下:

    {'image_dim_ordering':'th','epsilon':1e-07,'floatx':'float32','backend':'theano'}Theano加速配置在用户目录,也就是C:\Users\当前用户名\,新建.theanorc.txt。 这个路径可以通过修改Theano的configparser.py来改变。Theano装在Anaconda\Lib\site-packages里 .theanorc.txt的内容:

    [global]openmp=False device = gpu optimizer_including=cudnn #不用cudnn的话就不要这句,实际上不用加,只要刚刚配置到位就行floatX = float32 allow_input_downcast=True [lib]cnmem = 0.8 #theano黑科技,初始化显存比例[blas]ldflags= #加速库[gcc]cxxflags=-IC:\Anaconda2\MinGW [nvcc]fastmath = True --flags=-LC:\Anaconda2\libs #改成自己装的目录--compiler_bindir=D:\Microsoft Visual Studio 12.0\VC\bin #改成自己装的目录#最后记得把汉字全删了

    如果您的所安装的是CPU加速版本,那么.theanorc.txt文件配置如下:

    [global]openmp=Truedevice = cpufloatX = float32allow_input_downcast=True[gcc]cxxflags=-IC:\Anaconda2\MinGW

    之后可以验证keras是否安装成功,在命令行中输入Python命令进入Python变成命令行环境:

    >>>import kerasUsing Theano(Tensorflow) backend.>>>

    没有报错,那么Keras就已经成功安装了

    加速测试

    环境测试

    在命令行中进入Python环境,输入:

    import theano

    会出现一系列信息,包括显卡型号、浮点数类型、是否采用CNmem和cuDNN(如果使用了的话)等等,那么恭喜你,环境彻底配置成功。如果使用了Windows系统的读者,电脑上可能会出现,debug的字样,这是第一次使用,在编译生成运行库,属于正常现象。

    加速库测试

    Python环境下输入:

    import numpy id(numpy.dot) == id(numpy.core.multiarray.dot)

    如果得到的结果为False,说明你的除了gpu加速还得到了数学库blas加速,按照教程顺序配置的Linux用户是一定可以得到False结果的;Windows用户得到True也没有关系,因为Anaconda中已经内置了MKL加速库,如果想使用Openblas可以按照文末的联系方式联系我。

    速度测试

    新建一个文件test.py,内容为:

    from theano import function, config, shared, sandboximport theano.tensor as Timport numpyimport timevlen = 10 * 30 * 768 # 10 x #cores x # threads per core #这里可以加一两个0,多测试一下,记得去掉汉字iters = 1000rng = numpy.random.RandomState(22)x = shared(numpy.asarray(rng.rand(vlen), config.floatX))f = function([], T.exp(x))print(f.maker.fgraph.toposort())t0 = time.time()for i in xrange(iters): r = f()t1 = time.time()print('Looping %d times took %f seconds' % (iters, t1 - t0))print('Result is %s' % (r,))if numpy.any([isinstance(x.op, T.Elemwise) for x in f.maker.fgraph.toposort()]): print('Used the cpu')else: print('Used the gpu')

    在GTX 970显卡下,输出结果大概是0.21秒,在一百倍运算量下19秒,可以进行对比。理论上,相比较主频为3.3GHz的CPU,加速比应该是75倍,但不同的ssd和内存限制了IO接口传输速度。

    Keras中mnist数据集测试

    下载Keras开发包

    git clone https://github.com/fchollet/keras.gitcd keras/examples/python mnist_mlp.py

    程序无错进行,至此,keras安装完成。

    一个Anaconda3中配置遇到的异常解决方式

    目前发现使用Anaconda3安装theano时可能会有一个冲突:

    AttributeError:module ‘configparser’ has no attribute ‘SafeConfigParser’

    暂时只有用以下方法处理:

    对Anaconda3\Lib\site-packages\theano\configparser.py更改文件名,比如改为config_parser.py,在pycharm或其他IDE中随意运行一个cnn脚本,对遇到的每一个提示错误手动更改引用到的文件名为theano.config_parser,在将所有引用到这个文件的位置都改正后,应该就没有问题了。

    声明与联系方式

    由于作者水平和研究方向所限,无法对所有模块都非常精通,因此文档中不可避免的会出现各种错误、疏漏和不足之处。如果您在使用过程中有任何意见、建议和疑问,欢迎发送邮件到scp173.cool@gmail.com与中文文档作者取得联系.

    本教程不得用于任何形式的商业用途,如果需要转载请与作者或中文文档作者联系,如果发现未经允许复制转载,将保留追求其法律责任的权利。

    作者:SCP-173E-mail :scp173.cool@gmail.com如果您需要及时得到指导帮助,可以加微信:SCP173-cool,酌情打赏即可

    展开全文
  • OHIF Viewer是由提供零占用空间医学图像查看器。 它是一个可配置和可扩展渐进式Web应用程序,对支持图像存档具有即用支持。 | | 关于 OHIF医学影像查看器用于查看医学影像。 它可以从大多数来源和格式中检索...
  • ACM 产品正式商业

    2018-07-25 09:57:40
    产品介绍: ACM 产品正式商业化适用客户: 开发运维人员发布功能: - 配置集中管理和发布:配置按命名空间,分组,和ID来进行集中管理发布。 - 配置变更订阅:支持配置变更时,应用程序通过回掉接口处理变更通知。 ...
    产品介绍: ACM 产品正式商业化
    适用客户: 开发运维人员
    发布功能: - 配置集中管理和发布:配置按命名空间,分组,和ID来进行集中管理发布。 - 配置变更订阅:支持配置变更时,应用程序通过回掉接口处理变更通知。 - 配置加密:支持基于阿里云KMS的配置传输和存放全加密。 - 权限角色控制:基于RAM角色的细粒度权限控制,配置管理更加安全。 - 灰度发布:配置发布可根据IP粒度来进行灰度发布,配置发布更加安全。 - 版本管理和回滚:支持一键配置版本回滚,防止配置发错引起的应用故障。 - 配置订阅追踪:配置订阅深度追踪,配置收发情况一目了然。
    付费方式: 免费
    产品文档: https://help.aliyun.com/document_detail/59953.html
    展开全文
  • Linux信号功能的实现

    2010-11-08 16:31:00
    本文档Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档完整性,严禁用于任何商业用途。 msn: yfydz_no1@hotmail.com<br /> 来 源:http://yfydz.cublog.cn<br /> 1. 前言...
    本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,
    严禁用于任何商业用途。
    msn: yfydz_no1@hotmail.com
    来 源:http://yfydz.cublog.cn

    1. 前言

    信号是类UNIX系统中一个重要的进程控制方法,向中断一样,可通过向进程发送不同的信号临时中断
    程序的正常运行而进入信号处理程序或执行缺省的信号响应,如重新更新程序配置、终止进程等。

    在用户空间中,信号处理接口是通过一系列系统调用来实现的,包括signal, sigaction,
    sigsuspend, sigaltstack等,进程可通过以上这些接口定义进程的信号处理函数。如果要向其他进
    程发信号,可通过kill系统调用实现。

    在内核中对信号的处理程序主要定义在 kernel/signal.c, arch/***/kernel/signal.c等文件中,头
    文件在 include/linux/signal.h, include/asm/signal.h等。
     
    以下内核代码版本为2.6.19.2。
     
    2. 数据结构

    2.1 信号自身基本定义

    用于定义信号处理

    /* include/asm-generic/signal.h */
    // 信号处理函数格式
    typedef void __signalfn_t(int);
    typedef __signalfn_t __user *__sighandler_t;
    // 信号恢复函数
    typedef void __restorefn_t(void);
    typedef __restorefn_t __user *__sigrestore_t;
    // 三个预定义的信号处理函数值
    #define SIG_DFL ((__force __sighandler_t)0) /* default signal handling */
    #define SIG_IGN ((__force __sighandler_t)1) /* ignore signal */
    #define SIG_ERR ((__force __sighandler_t)-1) /* error return from signal */
     
    /* include/asm-i386/signal.h */
    #define _NSIG  64
    #define _NSIG_BPW 32
    #define _NSIG_WORDS (_NSIG / _NSIG_BPW)
    typedef unsigned long old_sigset_t;  /* at least 32 bits */
    // 信号集, 最多64个信号
    typedef struct {
     unsigned long sig[_NSIG_WORDS];
    } sigset_t;

    // 老的信号处理结构
    struct old_sigaction {
     __sighandler_t sa_handler;
     old_sigset_t sa_mask;
     unsigned long sa_flags;
     __sigrestore_t sa_restorer;
    };
    // 信号处理结构
    struct sigaction {
    // 信号处理函数
     __sighandler_t sa_handler;
    // 标志
     unsigned long sa_flags;
    // 信号恢复函数
     __sigrestore_t sa_restorer;
    // 信号集
     sigset_t sa_mask;  /* mask last for extensibility */
    };
    // 另一个定义
    struct k_sigaction {
     struct sigaction sa;
    };

    2.2 信号信息结构定义
    用于发送信号

    /* include/asm-generic/siginfo.h */
    typedef struct siginfo {
     int si_signo;
     int si_errno;
     int si_code;
     union {
      int _pad[SI_PAD_SIZE];
      /* kill() */
      struct {
       pid_t _pid;  /* sender's pid */
       __ARCH_SI_UID_T _uid; /* sender's uid */
      } _kill;
      /* POSIX.1b timers */
      struct {
       timer_t _tid;  /* timer id */
       int _overrun;  /* overrun count */
       char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
       sigval_t _sigval; /* same as below */
       int _sys_private;       /* not to be passed to user */
      } _timer;
      /* POSIX.1b signals */
      struct {
       pid_t _pid;  /* sender's pid */
       __ARCH_SI_UID_T _uid; /* sender's uid */
       sigval_t _sigval;
      } _rt;
      /* SIGCHLD */
      struct {
       pid_t _pid;  /* which child */
       __ARCH_SI_UID_T _uid; /* sender's uid */
       int _status;  /* exit code */
       clock_t _utime;
       clock_t _stime;
      } _sigchld;
      /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
      struct {
       void __user *_addr; /* faulting insn/memory ref. */
    #ifdef __ARCH_SI_TRAPNO
       int _trapno; /* TRAP # which caused the signal */
    #endif
      } _sigfault;
      /* SIGPOLL */
      struct {
       __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
       int _fd;
      } _sigpoll;
     } _sifields;
    } siginfo_t;
     
    3. 定义信号处理函数

    signal系统调用在内核中对应的是sys_signal,sigaction对应的是sys_sysaction:

    /* kernel/signal.c */
    /*
     * For backwards compatibility.  Functionality superseded by sigaction.
     */
    // signal函数已经只是为了后向兼容了,以后尽量还是使用sigaction实现为好
    asmlinkage unsigned long
    sys_signal(int sig, __sighandler_t handler)
    {
     struct k_sigaction new_sa, old_sa;
     int ret;
    // 填写新的信号处理结构参数
    // 最重要的是handler参数
     new_sa.sa.sa_handler = handler;
     new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
     sigemptyset(&new_sa.sa.sa_mask);
    // 进入do_sigaction函数处理
     ret = do_sigaction(sig, &new_sa, &old_sa);
    // 如果返回值为0(成功), 返回原来的信号处理函数
     return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
    }
     
    /* arch/i386/kernel/signal.c */
    // 注意输入的是老的信号处理结构
    asmlinkage int
    sys_sigaction(int sig, const struct old_sigaction __user *act,
           struct old_sigaction __user *oact)
    {
     struct k_sigaction new_ka, old_ka;
     int ret;
    // act相当于新的信号处理结构定义
     if (act) {
    // 从用户层空间拷贝信号处理结构参数
      old_sigset_t mask;
      if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
          __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
          __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
       return -EFAULT;
      __get_user(new_ka.sa.sa_flags, &act->sa_flags);
      __get_user(mask, &act->sa_mask);
      siginitset(&new_ka.sa.sa_mask, mask);
     }
    // 进入do_sigaction函数处理
     ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

    // 返回值为0(成功)时,返回老的信号处理结构信息
     if (!ret && oact) {
      if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
          __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
          __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
       return -EFAULT;
      __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
      __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
     }
     return ret;
    }

    这两个函数基本相同, 但一个是只处理一个信号处理函数,另一个则是处理一个信号处理结构, 参数
    要复杂一些,但这两个函数的核心都是do_sysaction:

    /* kernel/signal.c */
    int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
    {
     struct k_sigaction *k;
     sigset_t mask;
    // 检查一下参数是否合法
     if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig)))
      return -EINVAL;
    // k指向进程原来的信号处理结构
     k = &current->sighand->action[sig-1];
     spin_lock_irq(&current->sighand->siglock);
     if (signal_pending(current)) {
    // 目前进程在信号处理状态中
    // 此时不能设置信号处理程序
      /*
       * If there might be a fatal signal pending on multiple
       * threads, make sure we take it before changing the action.
       */
      spin_unlock_irq(&current->sighand->siglock);
      return -ERESTARTNOINTR;
     }
    // 将进程原来的信号处理结构备份到函数参数指定的原信号处理结构中
     if (oact)
      *oact = *k;
    // 要更新信号处理
     if (act) {
    // SIGKILL和SIGSTOP这两个信号是不能定义新的处理函数的
    // 相应标识始终被清除,因此即使设了也没用
      sigdelsetmask(&act->sa.sa_mask,
             sigmask(SIGKILL) | sigmask(SIGSTOP));
    // 将新信号结构复制到进程对应的信号处理结构中
      *k = *act;
      /*
       * POSIX 3.3.1.3:
       *  "Setting a signal action to SIG_IGN for a signal that is
       *   pending shall cause the pending signal to be discarded,
       *   whether or not it is blocked."
       *
       *  "Setting a signal action to SIG_DFL for a signal that is
       *   pending and whose default action is to ignore the signal
       *   (for example, SIGCHLD), shall cause the pending signal to
       *   be discarded, whether or not it is blocked"
       */
      if (act->sa.sa_handler == SIG_IGN ||
         (act->sa.sa_handler == SIG_DFL && sig_kernel_ignore(sig))) {
    // 如果新的信号处理函数是忽略该信号
       struct task_struct *t = current;
    // 清空信号掩码
       sigemptyset(&mask);
    // 设置掩码中相应信号的位
       sigaddset(&mask, sig);
    // 从该进程的信号队列中清除该信号
       rm_from_queue_full(&mask, &t->signal->shared_pending);
    // 从该进程的所有子线程的信号队列中清除该信号
       do {
        rm_from_queue_full(&mask, &t->pending);
        recalc_sigpending_tsk(t);
        t = next_thread(t);
       } while (t != current);
      }
     }
     spin_unlock_irq(&current->sighand->siglock);
     return 0;
    }

    4. 发送信号

    发送信号是通过kill(2)系统调用实现的,内核对应的处理函数是sys_kill:
    /* kernel/signal.c */
    asmlinkage long
    sys_kill(int pid, int sig)
    {
     struct siginfo info;
    // 填写信号信息结构参数, 该结构使用前没清零,也没用填满结构中所有参数
    // 信号值
     info.si_signo = sig;
     info.si_errno = 0;
     info.si_code = SI_USER;
     info.si_pid = current->tgid;
     info.si_uid = current->uid;
    // 向pid进程发送信号
     return kill_something_info(sig, &info, pid);
    }

    /* kernel/signal.h */
    /*
     * kill_something_info() interprets pid in interesting ways just like kill(2).
     *
     * POSIX specifies that kill(-1,sig) is unspecified, but what we have
     * is probably wrong.  Should make it like BSD or SYSV.
     */
    static int kill_something_info(int sig, struct siginfo *info, int pid)
    {
     if (!pid) {
    // pid为0, 是向一个进程组发信号
      return kill_pg_info(sig, info, process_group(current));
     } else if (pid == -1) {
    // pid为-1. 向所有其他组的进程发送信号
      int retval = 0, count = 0;
      struct task_struct * p;
      read_lock(&tasklist_lock);
      for_each_process(p) {
       if (p->pid > 1 && p->tgid != current->tgid) {
        int err = group_send_sig_info(sig, info, p);
        ++count;
        if (err != -EPERM)
         retval = err;
       }
      }
      read_unlock(&tasklist_lock);
      return count ? retval : -ESRCH;
     } else if (pid < 0) {
    // 其他的负pid值,将pid取反为正值后向进程组发送信号
      return kill_pg_info(sig, info, -pid);
     } else {
    // 一般情况, 向指定pid的进程发送信号
      return kill_proc_info(sig, info, pid);
     }
    }

    函数调用流程图:
    kill_proc_info        kill_pg_info
         |                      |
         V                      V
    kill_pid_info         __kill_pg_info
         |                      |
         |                      V
         |                __kill_pgrp_info
         |                      |
         +----------------------+
                    |
                    V
            group_send_sig_info
                    |
                    V
            __group_send_sig_info
                    |
                    V
                send_signal

    /* kernel/signal.c */
    static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
       struct sigpending *signals)
    {
     struct sigqueue * q = NULL;
     int ret = 0;
     /*
      * fast-pathed signals for kernel-internal things like SIGSTOP
      * or SIGKILL.
      */
    // 强制发送信号(SIGKILL或SIGSTOP), 直接发送
     if (info == SEND_SIG_FORCED)
      goto out_set;
     /* Real-time signals must be queued if sent by sigqueue, or
        some other real-time mechanism.  It is implementation
        defined whether kill() does so.  We attempt to do so, on
        the principle of least surprise, but since kill is not
        allowed to fail with EAGAIN when low on memory we just
        make sure at least one signal gets delivered and don't
        pass on the info struct.  */
    // 分配信号队列结构, 从sigqueue_cachep中分配(这个一个kmem_cache)
     q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
              (is_si_special(info) ||
               info->si_code >= 0)));
     if (q) {
    // 分配成功
    // 将该信号队列挂接到待发送信号链表末尾, 注意add_list是添加到链表头的
      list_add_tail(&q->list, &signals->list);
      switch ((unsigned long) info) {
    // 先看是否是几个特殊的info值然后填写相应的信号信息结构参数
      case (unsigned long) SEND_SIG_NOINFO:
    // 信号值
       q->info.si_signo = sig;
       q->info.si_errno = 0;
       q->info.si_code = SI_USER;
       q->info.si_pid = current->pid;
       q->info.si_uid = current->uid;
       break;
      case (unsigned long) SEND_SIG_PRIV:
    // 信号值
       q->info.si_signo = sig;
       q->info.si_errno = 0;
       q->info.si_code = SI_KERNEL;
       q->info.si_pid = 0;
       q->info.si_uid = 0;
       break;
      default:
    // 如是普通情况,复制信号信息
       copy_siginfo(&q->info, info);
       break;
      }
     } else if (!is_si_special(info)) {
    // 队列满了,普通用户的信号就被忽略,返回错误
      if (sig >= SIGRTMIN && info->si_code != SI_USER)
      /*
       * Queue overflow, abort.  We may abort if the signal was rt
       * and sent by user using something other than kill().
       */
       return -EAGAIN;
     }
    out_set:
    // 设置信号集中相应的信号标志
     sigaddset(&signals->signal, sig);
     return ret;
    }

    /* include/asm-i386/signal.h */
    #define sigaddset(set,sig)                 /
     (__builtin_constant_p(sig) ?       /
     __const_sigaddset((set),(sig)) :   /
     __gen_sigaddset((set),(sig)))
    static __inline__ void __gen_sigaddset(sigset_t *set, int _sig)
    {
     __asm__("btsl %1,%0" : "+m"(*set) : "Ir"(_sig - 1) : "cc");
    }
    static __inline__ void __const_sigaddset(sigset_t *set, int _sig)
    {
     unsigned long sig = _sig - 1;
     set->sig[sig / _NSIG_BPW] |= 1 << (sig % _NSIG_BPW);
    }

    5. 处理信号

    /* arch/i386/kernel/signal.c */
    /*
     * notification of userspace execution resumption
     * - triggered by the TIF_WORK_MASK flags
     */
    __attribute__((regparm(3)))
    void do_notify_resume(struct pt_regs *regs, void *_unused,
            __u32 thread_info_flags)
    {
     /* Pending single-step? */
     if (thread_info_flags & _TIF_SINGLESTEP) {
      regs->eflags |= TF_MASK;
      clear_thread_flag(TIF_SINGLESTEP);
     }
     /* deal with pending signal delivery */
    // 派发待发送的信号
     if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
      do_signal(regs);
     
     clear_thread_flag(TIF_IRET);
    }

    /*
     * Note that 'init' is a special process: it doesn't get signals it doesn't
     * want to handle. Thus you cannot kill init even with a SIGKILL even by
     * mistake.
     */
    static void fastcall do_signal(struct pt_regs *regs)
    {
     siginfo_t info;
     int signr;
     struct k_sigaction ka;
     sigset_t *oldset;
     /*
      * We want the common case to go fast, which
      * is why we may in certain cases get here from
      * kernel mode. Just return without doing anything
       * if so.  vm86 regs switched out by assembly code
       * before reaching here, so testing against kernel
       * CS suffices.
      */
    // 信号处理函数是在用户空间
     if (!user_mode(regs))
      return;
    // 原先的信息集指针
     if (test_thread_flag(TIF_RESTORE_SIGMASK))
      oldset = &current->saved_sigmask;
     else
      oldset = &current->blocked;
    // 找要发送的信号
     signr = get_signal_to_deliver(&info, &ka, regs, NULL);
     if (signr > 0) {
    // 找到一个信号
      /* Reenable any watchpoints before delivering the
       * signal to user space. The processor register will
       * have been cleared if the watchpoint triggered
       * inside the kernel.
       */
      if (unlikely(current->thread.debugreg[7]))
       set_debugreg(current->thread.debugreg[7], 7);
      /* Whee!  Actually deliver the signal.  */
    // 处理信号
      if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
       /* a signal was successfully delivered; the saved
        * sigmask will have been stored in the signal frame,
        * and will be restored by sigreturn, so we can simply
        * clear the TIF_RESTORE_SIGMASK flag */
       if (test_thread_flag(TIF_RESTORE_SIGMASK))
        clear_thread_flag(TIF_RESTORE_SIGMASK);
      }
      return;
     }
    // 无信号的情况
     /* Did we come from a system call? */
     if (regs->orig_eax >= 0) {
      /* Restart the system call - no handlers present */
      switch (regs->eax) {
      case -ERESTARTNOHAND:
      case -ERESTARTSYS:
      case -ERESTARTNOINTR:
       regs->eax = regs->orig_eax;
       regs->eip -= 2;
       break;
      case -ERESTART_RESTARTBLOCK:
       regs->eax = __NR_restart_syscall;
       regs->eip -= 2;
       break;
      }
     }
     /* if there's no signal to deliver, we just put the saved sigmask
      * back */
     if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
      clear_thread_flag(TIF_RESTORE_SIGMASK);
      sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
     }
    }

    /*
     * OK, we're invoking a handler
     */ 
    static int
    handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
           sigset_t *oldset, struct pt_regs * regs)
    {
     int ret;
     /* Are we from a system call? */
     if (regs->orig_eax >= 0) {
    // 判断当前是否在系统调用中
      /* If so, check system call restarting.. */
      switch (regs->eax) {
              case -ERESTART_RESTARTBLOCK:
       case -ERESTARTNOHAND:
        regs->eax = -EINTR;
        break;
       case -ERESTARTSYS:
        if (!(ka->sa.sa_flags & SA_RESTART)) {
         regs->eax = -EINTR;
         break;
        }
       /* fallthrough */
       case -ERESTARTNOINTR:
        regs->eax = regs->orig_eax;
        regs->eip -= 2;
      }
     }
     /*
      * If TF is set due to a debugger (PT_DTRACE), clear the TF flag so
      * that register information in the sigcontext is correct.
      */
     if (unlikely(regs->eflags & TF_MASK)
         && likely(current->ptrace & PT_DTRACE)) {
      current->ptrace &= ~PT_DTRACE;
      regs->eflags &= ~TF_MASK;
     }
     /* Set up the stack frame */
    // 建立进入信号处理函数前堆栈帧
     if (ka->sa.sa_flags & SA_SIGINFO)
      ret = setup_rt_frame(sig, ka, info, oldset, regs);
     else
      ret = setup_frame(sig, ka, oldset, regs);
     if (ret == 0) {
      spin_lock_irq(&current->sighand->siglock);
      sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
      if (!(ka->sa.sa_flags & SA_NODEFER))
       sigaddset(&current->blocked,sig);
      recalc_sigpending();
      spin_unlock_irq(&current->sighand->siglock);
     }
     return ret;
    }
     
    /* kernel/signal.c */
    // 找要发送的信号
    int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
         struct pt_regs *regs, void *cookie)
    {
     sigset_t *mask = &current->blocked;
     int signr = 0;
     try_to_freeze();
    relock:
     spin_lock_irq(&current->sighand->siglock);
     for (;;) {
      struct k_sigaction *ka;
    // unlikely的处理就是大部分情况下可忽略
      if (unlikely(current->signal->group_stop_count > 0) &&
          handle_group_stop())
       goto relock;
    // 从当前进程的信号队列中取信号
      signr = dequeue_signal(current, mask, info);
      if (!signr)
    // 无信号
       break; /* will return 0 */
    // 有信号
      if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
    // 当前进程是被跟踪调试中
       ptrace_signal_deliver(regs, cookie);
       /* Let the debugger run.  */
       ptrace_stop(signr, signr, info);
       /* We're back.  Did the debugger cancel the sig?  */
       signr = current->exit_code;
       if (signr == 0)
        continue;
       current->exit_code = 0;
       /* Update the siginfo structure if the signal has
          changed.  If the debugger wanted something
          specific in the siginfo structure then it should
          have updated *info via PTRACE_SETSIGINFO.  */
       if (signr != info->si_signo) {
        info->si_signo = signr;
        info->si_errno = 0;
        info->si_code = SI_USER;
        info->si_pid = current->parent->pid;
        info->si_uid = current->parent->uid;
       }
       /* If the (new) signal is now blocked, requeue it.  */
       if (sigismember(&current->blocked, signr)) {
        specific_send_sig_info(signr, info, current);
        continue;
       }
      }
    // 获取当前进程的信号处理函数
      ka = &current->sighand->action[signr-1];
      if (ka->sa.sa_handler == SIG_IGN) /* Do nothing.  */
    // 该信号是要忽略的,重新找下一信号
       continue;
      if (ka->sa.sa_handler != SIG_DFL) {
    // 定义了具体的函数处理函数, 复制要返回信号处理结构
       /* Run the handler.  */
       *return_ka = *ka;
       if (ka->sa.sa_flags & SA_ONESHOT)
        ka->sa.sa_handler = SIG_DFL;
       break; /* will return non-zero "signr" value */
      }
      /*
       * Now we are doing the default action for this signal.
       */
    // 否则执行系统缺省的信号处理
      if (sig_kernel_ignore(signr)) /* Default is nothing. */
       continue;
      /* Init gets no signals it doesn't want.  */
      if (current == child_reaper)
       continue;
      if (sig_kernel_stop(signr)) {
       /*
        * The default action is to stop all threads in
        * the thread group.  The job control signals
        * do nothing in an orphaned pgrp, but SIGSTOP
        * always works.  Note that siglock needs to be
        * dropped during the call to is_orphaned_pgrp()
        * because of lock ordering with tasklist_lock.
        * This allows an intervening SIGCONT to be posted.
        * We need to check for that and bail out if necessary.
        */
       if (signr != SIGSTOP) {
        spin_unlock_irq(&current->sighand->siglock);
        /* signals can be posted during this window */
        if (is_orphaned_pgrp(process_group(current)))
         goto relock;
        spin_lock_irq(&current->sighand->siglock);
       }
       if (likely(do_signal_stop(signr))) {
        /* It released the siglock.  */
        goto relock;
       }
       /*
        * We didn't actually stop, due to a race
        * with SIGCONT or something like that.
        */
       continue;
      }
      spin_unlock_irq(&current->sighand->siglock);
      /*
       * Anything else is fatal, maybe with a core dump.
       */
      current->flags |= PF_SIGNALED;
      if (sig_kernel_coredump(signr)) {
       /*
        * If it was able to dump core, this kills all
        * other threads in the group and synchronizes with
        * their demise.  If we lost the race with another
        * thread getting here, it set group_exit_code
        * first and our do_group_exit call below will use
        * that value and ignore the one we pass it.
        */
       do_coredump((long)signr, signr, regs);
      }
      /*
       * Death signals, no core dump.
       */
      do_group_exit(signr);
      /* NOTREACHED */
     }
     spin_unlock_irq(&current->sighand->siglock);
     return signr;
    }

    6. 结论

    Linux下的信号实现基本符合了APUE中对信号处理的描述, SIGKILL/SIGSTOP不可忽略, 发送给某进程
    的信号会排队, 信号可能会丢失等等.
    展开全文
  • * 然后可对"功能配置", "参数配置"等按照爱好进行个性设置; * * 2.修改完后请进入"模板配置", 分别点击每一个界面风格, * 进入编辑状态, 不进行任何修改分别提交一次; * * 3.添加或修改分类后,请更新JS;...
  • 模版名称:精简电影模版,蓝色电影模版,电影...选择“基本设置”,修改为您一些个性配置信息 广告位,需要自行修改与添加 广告位置 -后台-广告管理-调用里面标签,搜索原广告位替换即可 注意: 请勿乱修除模版
  • 上传源码,直接打开即可,config.asp为配置文件,可打开修改,无后台!V1.5 ASP商业版不包更新和修复BUG! V1.5外观没什么变动,只是修复了一个重要漏洞!*修复排版错位BUG!*优化网站页面,提升访问速度!*优化...
  • 开放了商业版所有功能能 开放了采集功能.采集规则.一健更新数据.下载资源.下载图片 代码进一步优化.对搜索引擎更友好.访问速度更快 2010.04.3 修正源码程序 程序简述: 1 asp Ajax开发,mssql数据库,前台...
  • GIS地图功能是现在越来越多项目标配,但是商业的的arcgis软件太贵,开源又有各种复杂的配置,如何简化这种配置呢,那就是使用脚本扫描知道文件夹下文件,把扫描到shp数据导入指定的空间数据库,然后对数据库...
  • 作业问答平台商业源码,天天作业答疑网程序,VIP在线学习网站源码 配置要求:ASP+AC ...程序基于asp+access制作,后台功能简单而强大,直接将源码上传至asp+access的空间即可进入后台管理操作,适合新手入门建站!
  • 文件控制,VA内置了完整文件重定向,可以方便控制内部App文件读写,基于此可以实现对文件保护加密等功能。 8. 注:以上控制能力均有实现代码或者实例以作参考。 VA其他特性 高性能 进程级“虚拟机...
  • 9、删除了网站配置设置里面没有用功能; 10、简单做了一下SEO,系统使用起来对百度和谷歌收录更具有亲和力; ========================================================= 免费版主要功能如下: 1.网站管理:...
  • 无sw-fw 描述 ...产品特点 更快的路由器 路由器和全球中间件 模型(MySQL和Eleasticsearch,Json可序列化,可访问数组) 查询生成器(MySQL和Elasticsearch...没有名称空间的功能重复 要求 作曲者1.x PHP 7.1以上 旋风4.
  • 通过计算各区公共服务设施达标率,发现城市社区生活圈内医疗设施和商业设施的配置相对完善,但公共文化设施和养老设施的配置明显不足。 在此基础上,从设施共享,功能混合,人口结构与活动特征区分三个方面,提出了...
  • 无sw-fw 描述 ...特征 更快的路由器 路由器和全球中间件 模型(MySQL和Eleasticsearch,Json可序列化,可访问数组) 查询生成器(MySQL和Elasticsearch) ...没有名称空间的功能重复 要求 作曲者1.x PHP 7.1以上 旋风4.2
  • 什么是GIS ... 根据区域地理环境特点,综合考虑资源配置、市场潜力、交通条件、地形特征、环境影响等因素,在区域范围内选择最佳位置,是GIS一个典型应用领域,充分体现了GIS的空间分析功能
  • 该毕业设计具体功能的获取过程主要使用文献法和走访调查法,通过网络调查和查阅网络资料来具体确定该软件的功能需求细节;在软件开发过程中,解决技术问题使用的方法是文献法,通过查阅课本、图书馆资料和网络在线...
  • 所有功能都以REST / GraphQL / WebSocket API形式公开。 服务器端组件 如果要自己运行Backend.AI群集,则需要安装和配置以下服务器端组件。 LGPLv3许可所有服务器端组件,以促进开源社区中非专有开放式创新...
  • 提供类似BBS的功能,用户可把销售秘诀贴在系统上,还可以进行某一方面销售技能的查询;销售费用管理;销售佣金管理。  6.电话营销和电话销售。  主要功能包括:电话本;生成电话列表,并把它们与客户、联系人和...
  • 具体功能点细节可浏览 Sym 功能点脑图,下面列出了 Sym 主要特性,说明 现代化 由来。 好用编辑器 Markdown:支持 GFM 语法以及一些扩展语法 格式调整:粗体、斜体、超链接、引用、列表等可以通过工具...
  • 丰富的配置功能和 SEO 搜索引擎优化。特别介绍:微博功能功能微博,流行微博界面;支持优酷、土豆、ku6、56网、新浪播客、凤凰视频;支持 at 功能、话题功能、表情功能;支持评论、转发;网站所有数据都可以分享...
  • 80年代则是GIS大发展时期,技术逐渐走向成熟,专业制造商开始出现,商业实用系统进入市场,应用领域迅速扩大。  我国在这方面虽然起步稍晚,但经过20余年努力,也有了相当发展。主要表现在以下三方面:...
  • 用最少的代码完成更多的功能,宗旨就是让WEB应用开发更简单、更快速。 为此ThinkPHP会不断吸收和融入更好的技术以保证其新鲜和活力,提供WEB应 用开发的最佳实践!经过6年来的不断重构和改进,ThinkPHP达到了一个新...
  • 商业主机管理软件已经逐渐在主机市场起到决定性市场空间,因为它部署更加快捷方便,主机管理也变得智能化和快捷化更有它强大功能是普通源码安装或一些开源软件达不到效果。在商业主机管理软件里,...
  • 随着计算机和电子通讯技术飞速发展和网络应用深化,网络版投票评选在活动中方便性和重要性,目前系统... 修正如下: 一、后台记录数据批量删除增加 二、增加项目和开发商字段 三、增加扩展功能的编辑功能

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 152
精华内容 60
关键字:

商业空间的功能配置