转:如何让程序屏蔽CTRL+C和CTRL+Z

一个程序在终端运行时,我们可以CTRL+C退出该程序或者CTRL+Z暂时停止该程序。那么有办法屏蔽这两个操作吗?

首先,得明白CTRL+C和CTRL+Z做了些什么。stty是Linux下的命令,输出和设置命令行控制参数。stty -a能输出所有命令行设置。如下是本博的命令行设置:
$stty -a
speed 38400 baud; rows 48; columns 159; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
可以看到CTRL+C就等于INTR,CTRL+Z就是SUSP,也就是说这两个分别会向程序发送SIGINT和SIGSTOP信号,这两个信号,一个用于终止进程,一个用于暂停进程,即挂起。

信号是Linux系统用于进程间通信的,内核也可以通过它们向程序发送消息。这些信号都很小,Sponge Liu写了篇文章《Linux内核信号处理机制介绍》,深入浅出的走了介绍。

接下来的问题就是,如何屏蔽两个信号。当然,你也可以通过设置stty的方式实现。可以在程序中屏蔽吗?如果可以,如何屏蔽?如果不可以,为啥?

很明显,肯定有些信号不能被屏蔽,比如中断,还应该有杀死进程的信号,要不然内核怎么做操作系统中的老大。实际上,SIGKILL和SIGSTOP信号是不能被屏蔽或阻止的,他们的默认动作总是会被执行的。

那就来个程序,直接屏蔽SIGINT信号吧.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdbool.h>

bool keep_going = true;

void ignore_notice()
{
  keep_going=false;
  printf("recieved SIGINT,and ignore it.\n");
}

void do_something()
{
  int i=0;
  while(i < 1000000)
    {
      i++;
    }
}

int main ()
{
  if(signal(SIGINT, ignore_notice) == SIG_ERR)
  {
    printf("Fail\n");
    return 1;
  }

  while(keep_going)
    do_something();

  printf("program normally exit.\n");
  return 0;
}

下面语句设置针对SIGINT的动作,第二个参数可以传入函数指针,指定处理方式为函数内容,也可以为SIG_IGN,忽略这个信号,或者SIG_DFL,执行默认的动作。
signal(SIGINT, ignore_notice) == SIG_ERR

转自:http://www.lingcc.com/2010/10/12/11305/

P、NP、NP-Complete、NP-hard问题

算法书中,总会有部分讨论到这个问题。绕来绕去的概念,头大。
这篇文章就再来好好学学这几个概念
Table of Contents

    1 遇到难题怎么办?
    2 什么是P、NP、NP-Complete和NP-hard
    3 P = NP ????
    4 参考

1 遇到难题怎么办?


遇到一个问题,通常我们思考的是如何解它。
于是就有了贪心、分治、动态规划等等算法;但也有一些问题,挠破了头也想不到高效的算法。
怎么办?

假如我们已经知道有那么几个问题,这个世界上所有的聪明人都没能找到高效的算法。
而且我们能把目前的问题通过等价转化的方式,变成这些已知问题的子问题。
这样就能证明我们不笨。

这个将一个问题,等价转换成另一个问题的子问题的方式,叫做 归约 (Reduction).
reduction-300x149.jpg
将问题A归约成问题B的子集

阅读剩余部分...

您已使用临时配置文件登录的解决办法

      昨天用魔方软件修改了管理员的默认用户文件夹,指向了一个新的目录,以前是c:\user\adminstrator.jjcc-105这样的,当初装机时不知道怎么弄的,变成了这个,还有一个正常的c:\user\adminstrator目录,但是用管理员账号登陆后,不会往c:\user\adminstrator里写配置,而是往c:\user\adminstrator.jjcc-105里面写,这样导致了一些问题。所以我改过来后,强制删除了c:\user\adminstrator.jjcc-105目录,结果WIN7蓝屏,自动重启后,所有配置丢失。再次重新配置,往桌面放文件夹,结果再次重启后,又丢失了,一切配置都归零,然后win7右下角提示:“您已使用临时配置文件登录。。。”表现就是上一次的所有操作都无效,都丢失了,桌面丢失,主题丢失。
desktop.gif

网上搜了很多方案,都是似是而非,甚至胡说八道的,最后还是微软最熟悉自己的系统,在微软官方解决了。
1.首先在命令行下执行whoami /user,找到当前用户的SID,确保是administrator这个超级管理员身份。

然后是微软的解决方案:
  1. 单击“开始”
  2. 在“开始搜索”(Windows Vista) 或“搜索程序和文件”(Windows 7) 区域,键入 regedit,然后按 Enter
  3. 如果出现 UAC 提示,请单击“继续”(Windows Vista) 或“是”(Windows 7)。
  4. 在“注册表编辑器”中,找到:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
  5. 在左窗格中,找到以“S-1-5”(SID 密钥)开头,后跟一长串数字的文件夹名称。然后单击每个文件夹,在右窗格中找到“ProfileImagePath”,双击验证其是否为出现错误的用户帐户配置文件。

    • 如果有两个文件夹以“S-1-5”开头,且后跟一长串数字,并且其中一个文件夹以“.bak”结尾。请将“.bak”文件夹更改为正常文件夹。为此,请执行以下步骤:
      1. 右键单击不含“.bak”的文件夹,选择“重命名”。然后在文件夹名称的末尾添加 .ba
      2. 右键单击含有“.bak”的文件夹,选择“重命名”。然后删除文件夹名称末尾的 .bak
      3. 右键单击含有“.ba”的文件夹,选择“重命名”。然后将文件夹名称末尾的 .ba 更改为 .bak
    • 如果您只有一个文件夹以“S-1-5”开头,且后跟一长串数字并以“.bak”结尾。请右键单击该文件夹,选择“重命名”。然后删除文件夹名称末尾的 .bak。
  6. 选择不含“.bak”的文件夹,在右窗格双击“RefCount”,键入 0,然后单击“确定”。
  7. 选择不含“.bak”的文件夹,在右窗格双击“状态”,键入 0,然后单击“确定”。
  8. 选择“注册表编辑器”。
  9. 重新启动计算机。
  10. 使用您的帐户再次登录。
         对注册表的后面两步操作是关键,这个网上的解决方案全都是胡扯,都没有提到这两步。详细的说明看这里:http://support.microsoft.com/kb/947215/zh-cn

教训:千万不要相信网上的野鸡教程,微软最熟悉自己的系统,遇到电脑问题,应该上微软官方去寻找答案,微软才是最权威的。

FTP传输之PORT、PASV模式辨析

FTP

FTP是File Transfer Protocol(文件传输协议)的缩写,用来在两台计算机之间互相传送文件。相比于HTTP,FTP协议要复杂得多。复杂的原因,是因为FTP协议要用到两个TCP连接,一个是命令链路,用来在FTP客户端与服务器之间传递命令;另一个是数据链路,用来上传或下载数据。

PORT & PASV

FTP协议有两种工作方式:PORT方式和PASV方式,中文意思为主动式和被动式。

PORT(主动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,客户端在命令链路上用PORT命令告诉服务器:“我打开了XXXX端口,你过来连接我”。于是服务器从20端口向客户端的XXXX端口发送连接请求,建立一条数据链路来传送数据。

PASV(被动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,服务器在命令链路上用PASV命令告诉客户端:“我打开了XXXX端口,你过来连接我”。于是客户端向服务器的XXXX端口发送连接请求,建立一条数据链路来传送数据。

从上面可以看出,两种方式的命令链路连接方法是一样的,而数据链路的建立方法就完全不同。而FTP的复杂性就在于此。

阅读剩余部分...

转:用Vmware Server搭建多虚拟环境 便于浏览器兼容性测试

目前正在梳理整个前端开发的流程及环境,也看了d2大家分享的关于前端各种自动化的演讲,便开始动手了
第一项是希望解决大家兼容性测试的问题,之前已经用虚拟机替换掉了ietester
但本地的虚拟机还是会出现团队成员不一致的情况,并且占用本地资源比较严重
在 美团 潘魏增 老兄帮助下,了解到美团目前在用的vmserver是很好的解决方案,再次感谢

同时参考了很多大家分享的东西,把自己遇到的问题也放出来和大家分享

下一步打算做一些前端自动化方面的脚本,希望和大家多学习,共进步

vmserver是vmware旗下的一款虚拟机服务器,可以通过web管理和操作虚拟机,同时支持多平台 windows、linux、macos等,免费的 可以在官网申请到授权码

这次我们选择的是linux版的vmware server

服务器环境:centos 5.5

vmserver版本:VMware-server-2.0.2-203138.i386

安装过程不详细叙述了 参考下面这篇文章即可,我也复制到最后给大家参考了

http://wuyizhaizhu.blog.163.com/blog/static/115151869201052201339515/

安装后通过web可以访问,进入管理端,在里面安装虚拟机即可

阅读剩余部分...

Android SDK 2.2开发环境安装

    昨晚安装了下安卓,鉴于安卓版本比较混乱,而且目前的主流版本是2.2,2.3,而且我手上的环境是2.2的,我选择的是比较保守的2.2的安装。在安装时遇到不少困惑,和书上以及视频里讲解的一些地方不太相同,大概是google频繁更新的问题吧,而且网上的一些教程有点老,会让新手困惑。这里记一下,供需要的参考。

1.第一步仍然是下载SDK的安装包,网址http://developer.android.com/index.html ,在down里可以看到最新的适合windows的版本是http://dl.google.com/android/android-sdk_r15-windows.zip,直接下载最新的,然后解压到e:\dev这样的目录中。

2.然后新建以下 几个文件夹
platforms,docs,samples,usb_driver,market_licensing,删除tools全部内容。

3.用迅雷等下载工具下载以下安装包,我们只下载2.0以上的SDK。8对应的是android 2.2,7对应的是android 2.1,往前类推。
谷歌api的安装包:
http://dl-ssl.google.com/android/repository/google_apis-5_r01.zip
http://dl-ssl.google.com/android/repository/google_apis-6_r01.zip
http://dl-ssl.google.com/android/repository/google_apis-7_r01.zip
http://dl-ssl.google.com/android/repository/google_apis-8_r02.zip

阅读剩余部分...

java nio 之MappedByteBuffer,高效文件/内存映射

MappedByteBuffer是java nio引入的文件内存映射方案,读写性能极高。NIO最主要的就是实现了对异步操作的支持。其中一种通过把一个套接字通道(SocketChannel)注册到一个选择器(Selector)中,不时调用后者的选择(select)方法就能返回满足的选择键(SelectionKey),键中包含了SOCKET事件信息。这就是select模型。
    SocketChannel的读写是通过一个类叫ByteBuffer(java.nio.ByteBuffer)来操作的.这个类本身的设计是不错的,比直接操作byte[]方便多了. ByteBuffer有两种模式:直接/间接.间接模式最典型(也只有这么一种)的就是HeapByteBuffer,即操作堆内存 (byte[]).但是内存毕竟有限,如果我要发送一个1G的文件怎么办?不可能真的去分配1G的内存.这时就必须使用"直接"模式,即 MappedByteBuffer,文件映射.
     先中断一下,谈谈操作系统的内存管理.一般操作系统的内存分两部分:物理内存;虚拟内存.虚拟内存一般使用的是页面映像文件,即硬盘中的某个(某些)特殊的文件.操作系统负责页面文件内容的读写,这个过程叫"页面中断/切换". MappedByteBuffer也是类似的,你可以把整个文件(不管文件有多大)看成是一个ByteBuffer.MappedByteBuffer 只是一种特殊的 ByteBuffer ,即是ByteBuffer的子类。 MappedByteBuffer 将文件直接映射到内存(这里的内存指的是虚拟内存,并不是物理内存)。通常,可以映射整个文件,如果文件比较大的话可以分段进行映射,只要指定文件的那个部分就可以。

三种方式:
              FileChannel提供了map方法来把文件影射为内存映像文件: MappedByteBuffer map(int mode,long position,long size); 可以把文件的从position开始的size大小的区域映射为内存映像文件,mode指出了 可访问该内存映像文件的方式:READ_ONLY,READ_WRITE,PRIVATE.                    
a. READ_ONLY,(只读): 试图修改得到的缓冲区将导致抛出 ReadOnlyBufferException.(MapMode.READ_ONLY)
 b. READ_WRITE(读/写): 对得到的缓冲区的更改最终将传播到文件;该更改对映射到同一文件的其他程序不一定是可见的。 (MapMode.READ_WRITE)
c. PRIVATE(专用): 对得到的缓冲区的更改不会传播到文件,并且该更改对映射到同一文件的其他程序也不是可见的;相反,会创建缓冲区已修改部分的专用副本。 (MapMode.PRIVATE)

三个方法:

a. fore();缓冲区是READ_WRITE模式下,此方法对缓冲区内容的修改强行写入文件
b. load()将缓冲区的内容载入内存,并返回该缓冲区的引用
c. isLoaded()如果缓冲区的内容在物理内存中,则返回真,否则返回假

三个特性:

    调用信道的map()方法后,即可将文件的某一部分或全部映射到内存中,映射内存缓冲区是个直接缓冲区,继承自ByteBuffer,但相对于ByteBuffer,它有更多的优点:

a. 读取快
b. 写入快
c. 随时随地写入

下面来看代码:

阅读剩余部分...

    Page :
  1. 1