Archive for April, 2013

作者:AngryFox 分类: Uncategorized April 28th, 2013 暂无评论

访问登记属性    android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限
获取错略位置    android.permission.ACCESS_COARSE_LOCATION,通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米
获取精确位置    android.permission.ACCESS_FINE_LOCATION,通过GPS芯片接收卫星的定位信息,定位精度达10米以内
访问定位额外命令    android.permission.ACCESS_LOCATION_EXTRA_COMMANDS,允许程序访问额外的定位提供者指令
获取模拟定位信息    android.permission.ACCESS_MOCK_LOCATION,获取模拟定位信息,一般用于帮助开发者调试应用
获取网络状态    android.permission.ACCESS_NETWORK_STATE,获取网络信息状态,如当前的网络连接是否有效
访问Surface Flinger    android.permission.ACCESS_SURFACE_FLINGER,Android平台上底层的图形显示支持,一般用于游戏或照相机预览界面和底层模式的屏幕截图
获取WiFi状态    android.permission.ACCESS_WIFI_STATE,获取当前WiFi接入的状态以及WLAN热点的信息
账户管理    android.permission.ACCOUNT_MANAGER,获取账户验证信息,主要为GMail账户信息,只有系统级进程才能访问的权限
验证账户    android.permission.AUTHENTICATE_ACCOUNTS,允许一个程序通过账户验证方式访问账户管理ACCOUNT_MANAGER相关信息
电量统计    android.permission.BATTERY_STATS,获取电池电量统计信息
绑定小插件    android.permission.BIND_APPWIDGET,允许一个程序告诉appWidget服务需要访问小插件的数据库,只有非常少的应用才用到此权限
绑定设备管理    android.permission.BIND_DEVICE_ADMIN,请求系统管理员接收者receiver,只有系统才能使用
绑定输入法    android.permission.BIND_INPUT_METHOD ,请求InputMethodService服务,只有系统才能使用
绑定RemoteView    android.permission.BIND_REMOTEVIEWS,必须通过RemoteViewsService服务来请求,只有系统才能用
绑定壁纸    android.permission.BIND_WALLPAPER,必须通过WallpaperService服务来请求,只有系统才能用
使用蓝牙    android.permission.BLUETOOTH,允许程序连接配对过的蓝牙设备
蓝牙管理    android.permission.BLUETOOTH_ADMIN,允许程序进行发现和配对新的蓝牙设备
变成砖头    android.permission.BRICK,能够禁用手机,非常危险,顾名思义就是让手机变成砖头
应用删除时广播    android.permission.BROADCAST_PACKAGE_REMOVED,当一个应用在删除时触发一个广播
收到短信时广播    android.permission.BROADCAST_SMS,当收到短信时触发一个广播
连续广播    android.permission.BROADCAST_STICKY,允许一个程序收到广播后快速收到下一个广播
WAP PUSH广播    android.permission.BROADCAST_WAP_PUSH,WAP PUSH服务收到后触发一个广播
拨打电话    android.permission.CALL_PHONE,允许程序从非系统拨号器里输入电话号码
通话权限    android.permission.CALL_PRIVILEGED,允许程序拨打电话,替换系统的拨号器界面
拍照权限    android.permission.CAMERA,允许访问摄像头进行拍照
改变组件状态    android.permission.CHANGE_COMPONENT_ENABLED_STATE,改变组件是否启用状态
改变配置    android.permission.CHANGE_CONFIGURATION,允许当前应用改变配置,如定位
改变网络状态    android.permission.CHANGE_NETWORK_STATE,改变网络状态如是否能联网
改变WiFi多播状态    android.permission.CHANGE_WIFI_MULTICAST_STATE,改变WiFi多播状态
改变WiFi状态    android.permission.CHANGE_WIFI_STATE,改变WiFi状态
清除应用缓存    android.permission.CLEAR_APP_CACHE,清除应用缓存
清除用户数据    android.permission.CLEAR_APP_USER_DATA,清除应用的用户数据
底层访问权限    android.permission.CWJ_GROUP,允许CWJ账户组访问底层信息
手机优化大师扩展权限    android.permission.CELL_PHONE_MASTER_EX,手机优化大师扩展权限
控制定位更新    android.permission.CONTROL_LOCATION_UPDATES,允许获得移动网络定位信息改变
删除缓存文件    android.permission.DELETE_CACHE_FILES,允许应用删除缓存文件
删除应用    android.permission.DELETE_PACKAGES,允许程序删除应用
电源管理    android.permission.DEVICE_POWER,允许访问底层电源管理
应用诊断    android.permission.DIAGNOSTIC,允许程序到RW到诊断资源
禁用键盘锁    android.permission.DISABLE_KEYGUARD,允许程序禁用键盘锁
转存系统信息    android.permission.DUMP,允许程序获取系统dump信息从系统服务
状态栏控制    android.permission.EXPAND_STATUS_BAR,允许程序扩展或收缩状态栏
工厂测试模式    android.permission.FACTORY_TEST,允许程序运行工厂测试模式
使用闪光灯    android.permission.FLASHLIGHT,允许访问闪光灯
强制后退    android.permission.FORCE_BACK,允许程序强制使用back后退按键,无论Activity是否在顶层
访问账户Gmail列表    android.permission.GET_ACCOUNTS,访问GMail账户列表
获取应用大小    android.permission.GET_PACKAGE_SIZE,获取应用的文件大小
获取任务信息    android.permission.GET_TASKS,允许程序获取当前或最近运行的应用
允许全局搜索    android.permission.GLOBAL_SEARCH,允许程序使用全局搜索功能
硬件测试    android.permission.HARDWARE_TEST,访问硬件辅助设备,用于硬件测试
注射事件    android.permission.INJECT_EVENTS,允许访问本程序的底层事件,获取按键、轨迹球的事件流
安装定位提供    android.permission.INSTALL_LOCATION_PROVIDER,安装定位提供
安装应用程序    android.permission.INSTALL_PACKAGES,允许程序安装应用
内部系统窗口    android.permission.INTERNAL_SYSTEM_WINDOW,允许程序打开内部窗口,不对第三方应用程序开放此权限
访问网络    android.permission.INTERNET,访问网络连接,可能产生GPRS流量
结束后台进程    android.permission.KILL_BACKGROUND_PROCESSES,允许程序调用killBackgroundProcesses(String).方法结束后台进程
管理账户    android.permission.MANAGE_ACCOUNTS,允许程序管理AccountManager中的账户列表
管理程序引用    android.permission.MANAGE_APP_TOKENS,管理创建、摧毁、Z轴顺序,仅用于系统
高级权限    android.permission.MTWEAK_USER,允许mTweak用户访问高级系统权限
社区权限    android.permission.MTWEAK_FORUM,允许使用mTweak社区权限
软格式化    android.permission.MASTER_CLEAR,允许程序执行软格式化,删除系统配置信息
修改声音设置    android.permission.MODIFY_AUDIO_SETTINGS,修改声音设置信息
修改电话状态    android.permission.MODIFY_PHONE_STATE,修改电话状态,如飞行模式,但不包含替换系统拨号器界面
格式化文件系统    android.permission.MOUNT_FORMAT_FILESYSTEMS,格式化可移动文件系统,比如格式化清空SD卡
挂载文件系统    android.permission.MOUNT_UNMOUNT_FILESYSTEMS,挂载、反挂载外部文件系统
允许NFC通讯    android.permission.NFC,允许程序执行NFC近距离通讯操作,用于移动支持
永久Activity    android.permission.PERSISTENT_ACTIVITY,创建一个永久的Activity,该功能标记为将来将被移除
处理拨出电话    android.permission.PROCESS_OUTGOING_CALLS,允许程序监视,修改或放弃播出电话
读取日程提醒    android.permission.READ_CALENDAR,允许程序读取用户的日程信息
读取联系人    android.permission.READ_CONTACTS,允许应用访问联系人通讯录信息
屏幕截图    android.permission.READ_FRAME_BUFFER,读取帧缓存用于屏幕截图
读取收藏夹和历史记录    com.android.browser.permission.READ_HISTORY_BOOKMARKS,读取浏览器收藏夹和历史记录
读取输入状态    android.permission.READ_INPUT_STATE,读取当前键的输入状态,仅用于系统
读取系统日志    android.permission.READ_LOGS,读取系统底层日志
读取电话状态    android.permission.READ_PHONE_STATE,访问电话状态
读取短信内容    android.permission.READ_SMS,读取短信内容
读取同步设置    android.permission.READ_SYNC_SETTINGS,读取同步设置,读取Google在线同步设置
读取同步状态    android.permission.READ_SYNC_STATS,读取同步状态,获得Google在线同步状态
重启设备    android.permission.REBOOT,允许程序重新启动设备
开机自动允许    android.permission.RECEIVE_BOOT_COMPLETED,允许程序开机自动运行
接收彩信    android.permission.RECEIVE_MMS,接收彩信
接收短信    android.permission.RECEIVE_SMS,接收短信
接收Wap Push    android.permission.RECEIVE_WAP_PUSH,接收WAP PUSH信息
录音    android.permission.RECORD_AUDIO,录制声音通过手机或耳机的麦克
排序系统任务    android.permission.REORDER_TASKS,重新排序系统Z轴运行中的任务
结束系统任务    android.permission.RESTART_PACKAGES,结束任务通过restartPackage(String)方法,该方式将在外来放弃
发送短信    android.permission.SEND_SMS,发送短信
设置Activity观察其    android.permission.SET_ACTIVITY_WATCHER,设置Activity观察器一般用于monkey测试
设置闹铃提醒    com.android.alarm.permission.SET_ALARM,设置闹铃提醒
设置总是退出    android.permission.SET_ALWAYS_FINISH,设置程序在后台是否总是退出
设置动画缩放    android.permission.SET_ANIMATION_SCALE,设置全局动画缩放
设置调试程序    android.permission.SET_DEBUG_APP,设置调试程序,一般用于开发
设置屏幕方向    android.permission.SET_ORIENTATION,设置屏幕方向为横屏或标准方式显示,不用于普通应用
设置应用参数    android.permission.SET_PREFERRED_APPLICATIONS,设置应用的参数,已不再工作具体查看addPackageToPreferred(String) 介绍
设置进程限制    android.permission.SET_PROCESS_LIMIT,允许程序设置最大的进程数量的限制
设置系统时间    android.permission.SET_TIME,设置系统时间
设置系统时区    android.permission.SET_TIME_ZONE,设置系统时区
设置桌面壁纸    android.permission.SET_WALLPAPER,设置桌面壁纸
设置壁纸建议    android.permission.SET_WALLPAPER_HINTS,设置壁纸建议
发送永久进程信号    android.permission.SIGNAL_PERSISTENT_PROCESSES,发送一个永久的进程信号
状态栏控制    android.permission.STATUS_BAR,允许程序打开、关闭、禁用状态栏
访问订阅内容    android.permission.SUBSCRIBED_FEEDS_READ,访问订阅信息的数据库
写入订阅内容    android.permission.SUBSCRIBED_FEEDS_WRITE,写入或修改订阅内容的数据库
显示系统窗口    android.permission.SYSTEM_ALERT_WINDOW,显示系统窗口
更新设备状态    android.permission.UPDATE_DEVICE_STATS,更新设备状态
使用证书    android.permission.USE_CREDENTIALS,允许程序请求验证从AccountManager
使用SIP视频    android.permission.USE_SIP,允许程序使用SIP视频服务
使用振动    android.permission.VIBRATE,允许振动
唤醒锁定    android.permission.WAKE_LOCK,允许程序在手机屏幕关闭后后台进程仍然运行
写入GPRS接入点设置    android.permission.WRITE_APN_SETTINGS,写入网络GPRS接入点设置
写入日程提醒    android.permission.WRITE_CALENDAR,写入日程,但不可读取
写入联系人    android.permission.WRITE_CONTACTS,写入联系人,但不可读取
写入外部存储    android.permission.WRITE_EXTERNAL_STORAGE,允许程序写入外部存储,如SD卡上写文件
写入Google地图数据    android.permission.WRITE_GSERVICES,允许程序写入Google Map服务数据
写入收藏夹和历史记录    com.android.browser.permission.WRITE_HISTORY_BOOKMARKS,写入浏览器历史记录或收藏夹,但不可读取
读写系统敏感设置    android.permission.WRITE_SECURE_SETTINGS,允许程序读写系统安全敏感的设置项
读写系统设置    android.permission.WRITE_SETTINGS,允许读写系统设置项
编写短信    android.permission.WRITE_SMS,允许编写短信
写入在线同步设置    android.permission.WRITE_SYNC_SETTINGS,写入Google在线同步设置

作者:AngryFox 分类: Uncategorized April 27th, 2013 暂无评论

对于<strong>nginx</strong>+php的一些网站,<strong>上传</strong>文件大小会受到多个方面的<strong>限制</strong>,一个是<strong>nginx</strong>本身的<strong>限制</strong>,<strong>限制</strong>了客户端<strong>上传</strong>文件的大小,一个是php.ini文件中默认了多个地方的设置。所以为了解决<strong>上传</strong>文件大小限定的问题必须要做出多处修改。以下整理了几个地方。

1、修改/usr/local/<strong>nginx</strong>/conf/<strong>nginx</strong>.conf 文件,查找 client_max_body_size 将后面的值设置为你想设置的值。比如:
<pre># pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            root           /home/www/htdocs;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /home/www/htdocs$fastcgi_script_name;
            include        fastcgi_params;

            client_max_body_size 35m;        #客户端<strong>上传</strong>文件大小设为35M
            client_body_temp_path /home/www/<strong>nginx</strong>_temp;        #设置临时目录
        }</pre>
2、修改php.ini

在php.ini里面查看如下行:
<pre>upload_max_filesize = 8M
post_max_size = 10M
memory_limit = 20M
max_execution_time=300
file_uploads = On

默认允许HTTP文件<strong>上传</strong>,此选项不能设置为OFF。
upload_tmp_dir =/tmp/www</pre>
在<strong>上传</strong>大文件时,你会有<strong>上传</strong>速度慢的感觉,当超过一定的时间,会报脚本执行超过30秒的错误,这是因为在php.ini配置文件中max_execution_time配置选项在作怪,其表示每个脚本最大允许执行时间(秒),0 表示没有<strong>限制</strong>。你可以适当调整max_execution_time的值,不推荐设定为0。
作者:AngryFox 分类: Uncategorized April 26th, 2013 暂无评论

http://www.cnblogs.com/stephen-liu74/archive/2012/02/15/2352512.html

一、概述:

在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。需要说明的是,这些操作的时间复杂度为O(1),即常量时间内完成次操作。Set可包含的最大元素数量是4294967295。
和List类型不同的是,Set集合中不允许出现重复的元素,这一点和C++标准库中的set容器是完全相同的。换句话说,如果多次添加相同元素,Set中将仅保留该元素的一份拷贝。和List类型相比,Set类型在功能上还存在着一个非常重要的特性,即在服务器端完成多个Sets之间的聚合计算操作,如unions、intersections和differences。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络IO开销。

二、相关命令列表:

命令原型 时间复杂度 命令描述 返回值
SADD key member [member ...] O(N) 时间复杂度中的N表示操作的成员数量。如果在插入的过程用,参数中有的成员在 Set中已经存在,该成员将被忽略,而其它成员仍将会被正常插入。如果执行该命令之前,该Key并不存在,该命令将会创建一个新的Set,此后再将参数中 的成员陆续插入。如果该Key的Value不是Set类型,该命令将返回相关的错误信息。 本次操作实际插入的成员数量。
SCARD key O(1) 获取Set中成员的数量。 返回Set中成员的数量,如果该Key并不存在,返回0。
SISMEMBER key member O(1) 判断参数中指定成员是否已经存在于与Key相关联的Set集合中。 1表示已经存在,0表示不存在,或该Key本身并不存在。
SMEMBERS key O(N) 时间复杂度中的N表示Set中已经存在的成员数量。获取与该Key关联的Set中所有的成员。 返回Set中所有的成员。
SPOP key O(1) 随机的移除并返回Set中的某一成员。 由于Set中元素的布局不受外部控制,因此无法像List那样确定哪个元素位于Set的头部或者尾部。 返回移除的成员,如果该Key并不存在,则返回nil。
SREM key member [member ...] O(N) 时间复杂度中的N表示被删除的成员数量。从与Key关联的Set中删除参数中指定的成员,不存在的参数成员将被忽略,如果该Key并不存在,将视为空Set处理。 从Set中实际移除的成员数量,如果没有则返回0。
SRANDMEMBER key O(1) 和SPOP一样,随机的返回Set中的一个成员,不同的是该命令并不会删除返回的成员。 返回随机位置的成员,如果Key不存在则返回nil。
SMOVE source destination member O(1) 原子性的将参数中的成员从source键移入到destination键所关联的 Set中。因此在某一时刻,该成员或者出现在source中,或者出现在destination中。如果该成员在source中并不存在,该命令将不会再 执行任何操作并返回0,否则,该成员将从source移入到destination。如果此时该成员已经在destination中存在,那么该命令仅是 将该成员从source中移出。如果和Key关联的Value不是Set,将返回相关的错误信息。 1表示正常移动,0表示source中并不包含参数成员。
SDIFF key [key ...] O(N) 时间复杂度中的N表示所有Sets中成员的总数量。返回参数中第一个Key所关联的Set和其后所有Keys所关联的Sets中成员的差异。如果Key不存在,则视为空Set。 差异结果成员的集合。
SDIFFSTORE destination key [key ...] O(N) 该命令和SDIFF命令在功能上完全相同,两者之间唯一的差别是SDIFF返回差异的结果成员,而该命令将差异成员存储在destination关联的Set中。如果destination键已经存在,该操作将覆盖它的成员。 返回差异成员的数量。
SINTER key [key ...] O(N*M) 时间复杂度中的N表示最小Set中元素的数量,M则表示参数中Sets的数量。该命令将返回参数中所有Keys关联的Sets中成员的交集。因此如果参数中任何一个Key关联的Set为空,或某一Key不存在,那么该命令的结果将为空集。 交集结果成员的集合。
SINTERSTORE destination key [key ...] O(N*M) 该命令和SINTER命令在功能上完全相同,两者之间唯一的差别是SINTER返回交集的结果成员,而该命令将交集成员存储在destination关联的Set中。如果destination键已经存在,该操作将覆盖它的成员。 返回交集成员的数量。
SUNION key [key ...] O(N) 时间复杂度中的N表示所有Sets中成员的总数量。该命令将返回参数中所有Keys关联的Sets中成员的并集。 并集结果成员的集合。
SUNIONSTORE destination key [key ...] O(N) 该命令和SUNION命令在功能上完全相同,两者之间唯一的差别是SUNION返回并集的结果成员,而该命令将并集成员存储在destination关联的Set中。如果destination键已经存在,该操作将覆盖它的成员。 返回并集成员的数量。

三、命令示例:


1. SADD/SMEMBERS/SCARD/SISMEMBER:
#在Shell命令行下启动Redis的客户端程序。
/> redis-cli
#插入测试数据,由于该键myset之前并不存在,因此参数中的三个成员都被正常插入。
redis 127.0.0.1:6379> sadd myset a b c
(integer) 3
#由于参数中的a在myset中已经存在,因此本次操作仅仅插入了d和e两个新成员。
redis 127.0.0.1:6379> sadd myset a d e
(integer) 2
#判断a是否已经存在,返回值为1表示存在。
redis 127.0.0.1:6379> sismember myset a
(integer) 1
#判断f是否已经存在,返回值为0表示不存在。
redis 127.0.0.1:6379> sismember myset f
(integer) 0
#通过smembers命令查看插入的结果,从结果可以,输出的顺序和插入顺序无关。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"
4) "b"
5) "e"
#获取Set集合中元素的数量。
redis 127.0.0.1:6379> scard myset
(integer) 5

2. SPOP/SREM/SRANDMEMBER/SMOVE:
#删除该键,便于后面的测试。
redis 127.0.0.1:6379> del myset
(integer) 1
#为后面的示例准备测试数据。
redis 127.0.0.1:6379> sadd myset a b c d
(integer) 4
#查看Set中成员的位置。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"
4) "b"
#从结果可以看出,该命令确实是随机的返回了某一成员。
redis 127.0.0.1:6379> srandmember myset
"c"
#Set中尾部的成员b被移出并返回,事实上b并不是之前插入的第一个或最后一个成员。
redis 127.0.0.1:6379> spop myset
"b"
#查看移出后Set的成员信息。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"
#从Set中移出a、d和f三个成员,其中f并不存在,因此只有a和d两个成员被移出,返回为2。
redis 127.0.0.1:6379> srem myset a d f
(integer) 2
#查看移出后的输出结果。
redis 127.0.0.1:6379> smembers myset
1) "c"
#为后面的smove命令准备数据。
redis 127.0.0.1:6379> sadd myset a b
(integer) 2
redis 127.0.0.1:6379> sadd myset2 c d
(integer) 2
#将a从myset移到myset2,从结果可以看出移动成功。
redis 127.0.0.1:6379> smove myset myset2 a
(integer) 1
#再次将a从myset移到myset2,由于此时a已经不是myset的成员了,因此移动失败并返回0。
redis 127.0.0.1:6379> smove myset myset2 a
(integer) 0
#分别查看myset和myset2的成员,确认移动是否真的成功。
redis 127.0.0.1:6379> smembers myset
1) "b"
redis 127.0.0.1:6379> smembers myset2
1) "c"
2) "d"
3) "a"

3. SDIFF/SDIFFSTORE/SINTER/SINTERSTORE:
#为后面的命令准备测试数据。
redis 127.0.0.1:6379> sadd myset a b c d
(integer) 4
redis 127.0.0.1:6379> sadd myset2 c
(integer) 1
redis 127.0.0.1:6379> sadd myset3 a c e
(integer) 3
#myset和myset2相比,a、b和d三个成员是两者之间的差异成员。再用这个结果继续和myset3进行差异比较,b和d是myset3不存在的成员。
redis 127.0.0.1:6379> sdiff myset myset2 myset3
1) "d"
2) "b"
#将3个集合的差异成员存在在diffkey关联的Set中,并返回插入的成员数量。
redis 127.0.0.1:6379> sdiffstore diffkey myset myset2 myset3
(integer) 2
#查看一下sdiffstore的操作结果。
redis 127.0.0.1:6379> smembers diffkey
1) "d"
2) "b"
#从之前准备的数据就可以看出,这三个Set的成员交集只有c。
redis 127.0.0.1:6379> sinter myset myset2 myset3
1) "c"
#将3个集合中的交集成员存储到与interkey关联的Set中,并返回交集成员的数量。
redis 127.0.0.1:6379> sinterstore interkey myset myset2 myset3
(integer) 1
#查看一下sinterstore的操作结果。
redis 127.0.0.1:6379> smembers interkey
1) "c"
#获取3个集合中的成员的并集。
redis 127.0.0.1:6379> sunion myset myset2 myset3
1) "b"
2) "c"
3) "d"
4) "e"
5) "a"
#将3个集合中成员的并集存储到unionkey关联的set中,并返回并集成员的数量。
redis 127.0.0.1:6379> sunionstore unionkey myset myset2 myset3
(integer) 5
#查看一下suiionstore的操作结果。
redis 127.0.0.1:6379> smembers unionkey
1) "b"
2) "c"
3) "d"
4) "e"
5) "a"

四、应用范围:

1). 可以使用Redis的Set数据类型跟踪一些唯一性数据,比如访问某一博客的唯一IP地址信息。对于此场景,我们仅需在每次访问该博客时将访问者的IP存入Redis中,Set数据类型会自动保证IP地址的唯一性。
2). 充分利用Set类型的服务端聚合操作方便、高效的特性,可以用于维护数据对象之间的关联关系。比如所有购买某一电子设备的客户ID被存储在一个指定的Set中,而购买另外一种电子产品的客户ID被存储在另外一个Set中,如果此时我们想获取有哪些客户同时购买了这两种商品时,Set的intersections命令就可以充分发挥它的方便和效率的优势了

作者:AngryFox 分类: Uncategorized April 26th, 2013 暂无评论

service crond status
/restart.sh /usr/local/bin/fdfs_storaged /etc/fdfs/storage.conf

vi /home/fastdfs/logs/storaged.log

tail -20f /home/fastdfs/logs/storaged.log

rm -f 2013-02-*

cat trackerx.kugou.com-access_2013022816.log |awk ‘{print $8}’|grep 404 |wc -l

netstat -an | grep 10.10.10.64 | awk ‘{arr[$5]++}END{for(key in arr)print key,arr[key]}’

cat access.log | grep /M01/200k/09/B0/9D/09B09D0F5719FC75454A4916AD9BD2DC.mp3 | grep -v 302 | more

cat /data1/logs/storage18.kugoug-access.log | grep dcdn.kugou.com | awk -F”|” ‘{arr[$4]++}END{for(key in arr)print key,arr[key]}’|sort -k4 -nr| head

/usr/local/bin/memcached -d -C -m 3072 -p 33210 -c 65535 -u root

chkconfig –level 3 sendmail off

ps axu | grep zip | awk ‘{print $2}’| xargs kill -SIGCONT

ps aux XXXXXX |awk ‘{print $2}’ -exec rm {} \

lsof /dev/sdb1

vmstat 2 3

rpm -ivh mediainfo-0.7.62-1.i386.CentOS_5.rpm

/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk ‘{print $2}’|tr -d “addr:”
05 /sbin/ifconfig|sed -n ‘/inet addr/s/^[^:]*:\([0-9.]\{7,15\}\) .*/\1/p’ | grep -v 127.0.0.1

mysqld 24289 kgmysql 51u REG 8,17 1024446550 19726677 /Db/mysql/3306/relaylog/relaylog.000367

iostat -x
iostat -d -m 1 10

ss -l 显示本地打开的所有端口
ss -pl 显示每个进程具体打开的socket
ss -t -a 显示所有tcp socket
ss -u -a 显示所有的UDP Socekt
ss -o state established ‘( dport = :smtp or sport = :smtp )’ 显示所有已建立的SMTP连接
ss -o state established ‘( dport = :http or sport = :http )’ 显示所有已建立的HTTP连接
ss -x src /tmp/.X11-unix/* 找出所有连接X服务器的进程
ss -s 列出当前socket详细信息:
解释:netstat是遍历/proc下面每个PID目录,ss直接读/proc/net下面的统计信息。所以ss执行的时候消耗资源以及消耗的时间都比netstat少很多

Usage: ss [ OPTIONS ]
       ss [ OPTIONS ] [ FILTER ]
   -h, --help           this message
   -V, --version        output version information
   -n, --numeric        don't resolve service names
   -r, --resolve       resolve host names
   -a, --all            display all sockets
   -l, --listening      display listening sockets
   -o, --options       show timer information
   -e, --extended      show detailed socket information
   -m, --memory        show socket memory usage
   -p, --processes      show process using socket
   -i, --info           show internal TCP information
   -s, --summary        show socket usage summary

   -4, --ipv4          display only IP version 4 sockets
   -6, --ipv6          display only IP version 6 sockets
   -0, --packet display PACKET sockets
   -t, --tcp            display only TCP sockets
   -u, --udp            display only UDP sockets
   -d, --dccp           display only DCCP sockets
   -w, --raw            display only RAW sockets
   -x, --unix           display only Unix domain sockets
   -f, --family=FAMILY display sockets of type FAMILY

   -A, --query=QUERY
       QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]

   -F, --filter=FILE   read filter information from FILE
       FILTER := [ state TCP-STATE ] [ EXPRESSION ]
作者:AngryFox 分类: Uncategorized April 24th, 2013 暂无评论

signal(SIGCLD,SIG_IGN)
SIGCHLD的语义为:子进程状态改变后产生此信号,父进程需要调用一个wait函数以确定发生了什么。
对于SIGCLD的早期处理方式如下:如果进程特地设置该信号的配置为SIG_IGN,则调用进程的子进程将不产生僵死进程。
如果将SIGCLD的配置设置为捕捉,则内核立即检查是否有子进程准备好被等待,如果是这样,则调用SIGCLD处理程序。

《unix环境高级编程》(apue)
APUE上SIGCLD语义写的有点不清楚,到底我们的系统是如何来处理SIGCLD信号呢?
1.SIG_DFL :默认的处理方式是不理会这个信号,但是也不会丢弃子进行状态,所以如果不用wait,waitpid
对其子进行进行状态信息回收,会产生僵尸进程。
2.SIG_IGN :忽略的处理方式,这个方式和默认的忽略是不一样的语意,暂且我们把忽略定义为SIG_IGN,
在这种方式下,子进程状态信息会被丢弃,也就是自动回收了,所以不会产生僵尸进程,但是问题也就来了,
wait,waitpid却无法捕捉到子进程状态信息了,如果你随后调用了wait,那么会阻塞到所有的子进程结束,并返
回错误ECHILD,也就是没有子进程等待。
APUE中P248叙述SIGCHLD如果配置成SIG_IGN也不会产生僵尸进程。是否系统SIG_IGN配置下,对
SIGCLD,SIGCHLD做出的处理方式是相同的。
3.自定义处理方式:SIGCLD会立即检查是否有子进程准好被等待,这便是SIGCLD最大漏洞了,一旦在信号
处理函数中加入了信号处理方式重建的步骤,那么每次设置SIGCLD处理方式时,都会去检查是否有信号到来,
如果此时信号的确到来了,先是调用自定义信号处理函数,然后是调用信号处理方式重建函数,在重建配置的
时候,会去检查信号是否到来,此时信号未被处理,会再次触发自定义信号处理函数,一直循环。
所以在处理SIGCLD时,应该先wait处理掉了信号信息后,再进行信号处理方式重建。
SIGCHLD在配置信号处理方式时,是不会立即检查是否有子进程准备好被扽带,也不会在此时调用信号处理函数。

作者:AngryFox 分类: Uncategorized April 21st, 2013 暂无评论

在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程. 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父进程……

一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁, 而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是 使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)

2. 僵尸进程的危害

由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 那么不会因为父进程太忙来不及waid子进程,或者说不知道 子进程什么时候结束,而丢失子进程结束时的状态信息呢? 不会.因为UNIX提供了一种机制可以保证 只要父进程想知道子进程结束时的状态信息, 就可以得到. 这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等. 但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等), 直到父进程通过wait / waitpid来取时才释放. 但这样就导致了问题,如果你进程不调用wait / waitpid的话, 那么保留的那段信息就不会 释放,其进程号就会一定被占用,但是系统所能使用的进程号是有限的,如果大量的产生 僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免.

3.僵尸进程的避免

1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起

2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收

3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号

4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。 下面就是Stevens给的采用两次folk避免僵尸进程的示例.

3、僵尸进程的处理: 它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态; 存在的问题:如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程,系统的性能可能会收到影响。 ** 如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。 4、子进程结束后为什么要进入僵尸状态? * 因为父进程可能要取得子进程的退出状态等信息。 5、僵尸状态是每个子进程比经过的状态吗? 是的。 * 任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。 * 如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。 6、如何查看僵尸进程: $ ps -el 其中,有标记为Z的进程就是僵尸进程 S代表休眠状态;D代表不可中断的休眠状态;R代表运行状态;Z代表僵死状态;T代表停止或跟踪状态

wait 系统调用

系统中的僵尸进程都要由wait系统调用来回收,下面就通过实战看一看wait的具体用法:

wait的函数原型是:

#include

#include

pid_t wait(int *status);

进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。

参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样:

pid = wait(NULL);

如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。

下面就让我们用一个例子来实战应用一下wait调用:

#include

#include

#include

#include

#include

#include

int main()

{

pid_t pc, pr;

pc = fork();

if ( pc < 0 )

{

printf("create child prcocess error: %s\n", strerror(errno));

exit(1);

}

else if ( pc == 0)

{

printf("I am child process with pid %d \n", getpid());

sleep(3);

exit(0);

}

else

{

printf("Now in parent process, pid = %d\n", getpid());

printf("I am waiting child process to exit.\n");

pr = wait(NULL);

if ( pr > 0 )

printf(“I catched a child process with pid of %d\n”, pr);

else

printf(“error: %s\n.\n”, strerror(errno));

}

exit(0);

}

编译并运行:

$ gcc wait1.c -o wait1

$ ./wait1

I am child process with pid 2351

Now in parent process, pid = 2350

I am waiting child process to exit.

I catched a child process with pid of 2351

可以明显注意到,在第2行结果打印出来前有10秒钟的等待时间,这就是我们设定的让子进程睡眠的时间,只有子进程从睡眠中苏醒过来,它才能正常退 出,也就才能被父进程捕捉到。其实这里我们不管设定子进程睡眠的时间有多长,父进程都会一直等待下去,读者如果有兴趣的话,可以试着自己修改一下这个数 值,看看会出现怎样的结果。

如果参数status的值不是NULL,wait就会把子进程退出时的状态取出并存入其中,这是一个整数值(int),指出了子进程是正常退出还是 被非正常结束的(一个进程也可以被其他进程用信号结束,我们将在以后的文章中介绍),以及正常结束时的返回值,或被哪一个信号结束的等信息。由于这些信息 被存放在一个整数的不同二进制位中,所以用常规的方法读取会非常麻烦,人们就设计了一套专门的宏(macro)来完成这项工作,下面我们来学习一下其中最 常用的两个:

1,WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。

(请注意,虽然名字一样,这里的参数status并不同于wait唯一的参数–指向整数的指针status,而是那个指针所指向的整数,切记不要搞混了。)

2, WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status) 就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说, WIFEXITED返回0,这个值就毫无意义。

下面通过例子来实战一下我们刚刚学到的内容:

#include

#include

#include

int main()

{

int status;

pid_t pc, pr;

pc = fork();

if ( pc < 0)

printf(“error occured.\n”);

else if ( pc == 0 )

{

printf(“This is child process with pid of %d.\n”, getpid());

exit(3);

}

else

{

pr = wait(&status);

if ( WIFEXITED(status) )

{

printf(“The child process %d exit normally.\n”, pr);

printf(“the return code is %d.\n”, WEXITSTATUS(status));

}

else

printf(“The child process %d exit abnormally.\n”, pr);

}

exit(0);

}

编译并运行:

$ gcc wait2.c -o wait2

$ ./wait2

This is child process with pid of 1538.

the child process 1538 exit normally.

the return code is 3.

父进程准确捕捉到了子进程的返回值3,并把它打印了出来。

当然,处理进程退出状态的宏并不止这两个,但它们当中的绝大部分在平时的编程中很少用到,就也不在这里浪费篇幅介绍了,有兴趣的读者可以自己参阅Linux man pages去了解它们的用法。

作者:AngryFox 分类: Uncategorized April 21st, 2013 暂无评论

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念、Linux对信号机制的大致实现方法、如何使用信号,以及有关信号的几个系统调用。

信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断。从它的命名可以看出,它的实质和使用很象中断。所以,信号可以说是进程控制的一部分。

一、信号的基本概念

本节先介绍信号的一些基本概念,然后给出一些基本的信号类型和信号对应的事件。基本概念对于理解和使用信号,对于理解信号机制都特别重要。下面就来看看什么是信号。

1、基本概念

软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。注意,信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。

收 到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处 理。第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信 号的缺省操作是使得进程终止。进程通过系统调用signal来指定进程对某个信号的处理行为。

在进程表的表项中有一个软中断信号域,该域中每一位对应一个信号,当有信号发送给进程时,对应位置位。由此可以看出,进程对不同的信号可以同时保留,但对于同一个信号,进程并不知道在处理之前来过多少个。

2、信号的类型

发出信号的原因很多,这里按发出信号的原因简单分类,以了解各种信号:

(1) 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。
(2) 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。
(3) 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。
(4) 与执行系统调用时遇到非预测错误条件相关的信号。如执行一个并不存在的系统调用。
(5) 在用户态下的进程发出的信号。如进程调用系统调用kill向其他进程发送信号。
(6) 与终端交互相关的信号。如用户关闭一个终端,或按下break键等情况。
(7) 跟踪进程执行的信号。

Linux支持的信号列表如下。很多信号是与机器的体系结构相关的,首先列出的是POSIX.1中列出的信号:

信号 值 处理动作 发出信号的原因
———————————————————————-
SIGHUP 1 A 终端挂起或者控制进程终止
SIGINT 2 A 键盘中断(如break键被按下)
SIGQUIT 3 C 键盘的退出键被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)发出的退出指令
SIGFPE 8 C 浮点异常
SIGKILL 9 AEF Kill信号
SIGSEGV 11 C 无效的内存引用
SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道
SIGALRM 14 A 由alarm(2)发出的信号
SIGTERM 15 A 终止信号
SIGUSR1 30,10,16 A 用户自定义信号1
SIGUSR2 31,12,17 A 用户自定义信号2
SIGCHLD 20,17,18 B 子进程结束信号
SIGCONT 19,18,25 进程继续(曾被停止的进程)
SIGSTOP 17,19,23 DEF 终止进程
SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键
SIGTTIN 21,21,26 D 后台进程企图从控制终端读
SIGTTOU 22,22,27 D 后台进程企图从控制终端写

下面的信号没在POSIX.1中列出,而在SUSv2列出

信号 值 处理动作 发出信号的原因
——————————————————————–
SIGBUS 10,7,10 C 总线错误(错误的内存访问)
SIGPOLL A Sys V定义的Pollable事件,与SIGIO同义
SIGPROF 27,27,29 A Profiling定时器到
SIGSYS 12,-,12 C 无效的系统调用 (SVID)
SIGTRAP 5 C 跟踪/断点捕获
SIGURG 16,23,21 B Socket出现紧急条件(4.2 BSD)
SIGVTALRM 26,26,28 A 实际时间报警时钟信号(4.2 BSD)
SIGXCPU 24,24,30 C 超出设定的CPU时间限制(4.2 BSD)
SIGXFSZ 25,25,31 C 超出设定的文件大小限制(4.2 BSD)

(对于SIGSYS,SIGXCPU,SIGXFSZ,以及某些机器体系结构下的SIGBUS,Linux缺省的动作是A (terminate),SUSv2 是C (terminate and dump core))。

下面是其它的一些信号

信号 值 处理动作 发出信号的原因
———————————————————————-
SIGIOT 6 C IO捕获指令,与SIGABRT同义
SIGEMT 7,-,7
SIGSTKFLT -,16,- A 协处理器堆栈错误
SIGIO 23,29,22 A 某I/O操作现在可以进行了(4.2 BSD)
SIGCLD -,-,18 A 与SIGCHLD同义
SIGPWR 29,30,19 A 电源故障(System V)
SIGINFO 29,-,- A 与SIGPWR同义
SIGLOST -,-,- A 文件锁丢失
SIGWINCH 28,28,20 B 窗口大小改变(4.3 BSD, Sun)
SIGUNUSED -,31,- A 未使用的信号(will be SIGSYS)

(在这里,- 表示信号没有实现;有三个值给出的含义为,第一个值通常在Alpha和Sparc上有效,中间的值对应i386和ppc以及sh,最后一个值对应mips。信号29在Alpha上为SIGINFO / SIGPWR ,在Sparc上为SIGLOST。)

处理动作一项中的字母含义如下
A 缺省的动作是终止进程
B 缺省的动作是忽略此信号
C 缺省的动作是终止进程并进行内核映像转储(dump core)
D 缺省的动作是停止进程
E 信号不能被捕获
F 信号不能被忽略

上 面介绍的信号是常见系统所支持的。以表格的形式介绍了各种信号的名称、作用及其在默认情况下的处理动作。各种默认处理动作的含义是:终止程序是指进程退 出;忽略该信号是将该信号丢弃,不做处理;停止程序是指程序挂起,进入停止状况以后还能重新进行下去,一般是在调试的过程中(例如ptrace系统调 用);内核映像转储是指将进程数据在内存的映像和进程在内核结构中存储的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员提 供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。

注意 信号SIGKILL和SIGSTOP既不能被捕捉,也不能被忽略。信号SIGIOT与SIGABRT是一个信号。可以看出,同一个信号在不同的系统中值可能不一样,所以建议最好使用为信号定义的名字,而不要直接使用信号的值。

二、信 号 机 制

上 一节中介绍了信号的基本概念,在这一节中,我们将介绍内核如何实现信号机制。即内核如何向一个进程发送信号、进程如何接收一个信号、进程怎样控制自己对信 号的反应、内核在什么时机处理和怎样处理进程收到的信号。还要介绍一下setjmp和longjmp在信号中起到的作用。

1、内核对信号的基本处理方法

内 核给一个进程发送软中断信号的方法,是在进程所在的进程表项的信号域设置对应于该信号的位。这里要补充的是,如果信号发送给一个正在睡眠的进程,那么要看 该进程进入睡眠的优先级,如果进程睡眠在可被中断的优先级上,则唤醒进程;否则仅设置进程表中信号域相应的位,而不唤醒进程。这一点比较重要,因为进程检 查是否收到信号的时机是:一个进程在即将从内核态返回到用户态时;或者,在一个进程要进入或离开一个适当的低调度优先级睡眠状态时。

内核处理一个进程收到的信号的时机是在一个进程从内核态返回用户态时。所以,当一个进程在内核态下运行时,软中断信号并不立即起作用,要等到将返回用户态时才处理。进程只有处理完信号才会返回用户态,进程在用户态下不会有未处理完的信号。

内 核处理一个进程收到的软中断信号是在该进程的上下文中,因此,进程必须处于运行状态。前面介绍概念的时候讲过,处理信号有三种类型:进程接收到信号后退 出;进程忽略该信号;进程收到信号后执行用户设定用系统调用signal的函数。当进程接收到一个它忽略的信号时,进程丢弃该信号,就象没有收到该信号似 的继续运行。如果进程收到一个要捕捉的信号,那么进程从内核态返回用户态时执行用户定义的函数。而且执行用户定义的函数的方法很巧妙,内核是在用户栈上创 建一个新的层,该层中将返回地址的值设置成用户定义的处理函数的地址,这样进程从内核返回弹出栈顶时就返回到用户定义的函数处,从函数返回再弹出栈顶时, 才返回原先进入内核的地方。这样做的原因是用户定义的处理函数不能且不允许在内核态下执行(如果用户定义的函数在内核态下运行的话,用户就可以获得任何权 限)。

在信号的处理方法中有几点特别要引起注意。第一,在一些系统中,当一个进程处理完中断信号返回用户态之前,内核清除用户区中设 定的对该信号的处理例程的地址,即下一次进程对该信号的处理方法又改为默认值,除非在下一次信号到来之前再次使用signal系统调用。这可能会使得进程 在调用signal之前又得到该信号而导致退出。在BSD中,内核不再清除该地址。但不清除该地址可能使得进程因为过多过快的得到某个信号而导致堆栈溢 出。为了避免出现上述情况。在BSD系统中,内核模拟了对硬件中断的处理方法,即在处理某个中断时,阻止接收新的该类中断。

第二个要 引起注意的是,如果要捕捉的信号发生于进程正在一个系统调用中时,并且该进程睡眠在可中断的优先级上,这时该信号引起进程作一次longjmp,跳出睡眠 状态,返回用户态并执行信号处理例程。当从信号处理例程返回时,进程就象从系统调用返回一样,但返回了一个错误代码,指出该次系统调用曾经被中断。这要注 意的是,BSD系统中内核可以自动地重新开始系统调用。

第三个要注意的地方:若进程睡眠在可中断的优先级上,则当它收到一个要忽略的信号时,该进程被唤醒,但不做longjmp,一般是继续睡眠。但用户感觉不到进程曾经被唤醒,而是象没有发生过该信号一样。

第 四个要注意的地方:内核对子进程终止(SIGCLD)信号的处理方法与其他信号有所区别。当进程检查出收到了一个子进程终止的信号时,缺省情况下,该进程 就象没有收到该信号似的,如果父进程执行了系统调用wait,进程将从系统调用wait中醒来并返回wait调用,执行一系列wait调用的后续操作(找 出僵死的子进程,释放子进程的进程表项),然后从wait中返回。SIGCLD信号的作用是唤醒一个睡眠在可被中断优先级上的进程。如果该进程捕捉了这个 信号,就象普通信号处理一样转到处理例程。如果进程忽略该信号,那么系统调用wait的动作就有所不同,因为SIGCLD的作用仅仅是唤醒一个睡眠在可被 中断优先级上的进程,那么执行wait调用的父进程被唤醒继续执行wait调用的后续操作,然后等待其他的子进程。

如果一个进程调用signal系统调用,并设置了SIGCLD的处理方法,并且该进程有子进程处于僵死状态,则内核将向该进程发一个SIGCLD信号。

2、setjmp和longjmp的作用

前面在介绍信号处理机制时,多次提到了setjmp和longjmp,但没有仔细说明它们的作用和实现方法。这里就此作一个简单的介绍。

在 介绍信号的时候,我们看到多个地方要求进程在检查收到信号后,从原来的系统调用中直接返回,而不是等到该调用完成。这种进程突然改变其上下文的情况,就是 使用setjmp和longjmp的结果。setjmp将保存的上下文存入用户区,并继续在旧的上下文中执行。这就是说,进程执行一个系统调用,当因为资 源或其他原因要去睡眠时,内核为进程作了一次setjmp,如果在睡眠中被信号唤醒,进程不能再进入睡眠时,内核为进程调用longjmp,该操作是内核 为进程将原先setjmp调用保存在进程用户区的上下文恢复成现在的上下文,这样就使得进程可以恢复等待资源前的状态,而且内核为setjmp返回1,使 得进程知道该次系统调用失败。这就是它们的作用。

三、有关信号的系统调用

前面两节已经介绍了有关信号的大部分知 识。这一节我们来了解一下这些系统调用。其中,系统调用signal是进程用来设定某个信号的处理方法,系统调用kill是用来发送信号给指定进程的。这 两个调用可以形成信号的基本操作。后两个调用pause和alarm是通过信号实现的进程暂停和定时器,调用alarm是通过信号通知进程定时器到时。所 以在这里,我们还要介绍这两个调用。

1、signal 系统调用

系统调用signal用来设定某个信号的处理方法。该调用声明的格式如下:
void (*signal(int signum, void (*handler)(int)))(int);
在使用该调用的进程中加入以下头文件:
#include

上述声明格式比较复杂,如果不清楚如何使用,也可以通过下面这种类型定义的格式来使用(POSIX的定义):
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
但这种格式在不同的系统中有不同的类型定义,所以要使用这种格式,最好还是参考一下联机手册。

在调用中,参数signum指出要设置处理方法的信号。第二个参数handler是一个处理函数,或者是
SIG_IGN:忽略参数signum所指的信号。
SIG_DFL:恢复参数signum所指信号的处理方法为默认值。

传递给信号处理例程的整数参数是信号值,这样可以使得一个信号处理例程处理多个信号。系统调用signal返回值是指定信号signum前一次的处理例程或者错误时返回错误代码SIG_ERR。下面来看一个简单的例子:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
void sigroutine(int dunno) {
switch (dunno) {
case 1:
printf("Get a signal -- SIGHUP ");
break;
case 2:
printf("Get a signal -- SIGINT ");
break;
case 3:
printf("Get a signal -- SIGQUIT ");
break;
}
return;
} 

int main() {
printf("process id is %d ",getpid());
signal(SIGHUP, sigroutine); /
struct timeval it_value;
}; 

该结构中timeval结构定义如下:
struct timeval {
long tv_sec;
long tv_usec;
};

在setitimer 调用中,参数ovalue如果不为空,则其中保留的是上次调用设定的值。定时器将it_value递减到0时,产生一个信号,并将it_value的值设 定为it_interval的值,然后重新开始计时,如此往复。当it_value设定为0时,计时器停止,或者当它计时到期,而it_interval 为0时停止。调用成功时,返回0;错误时,返回-1,并设置相应的错误代码errno:
EFAULT:参数value或ovalue是无效的指针。
EINVAL:参数which不是ITIMER_REAL、ITIMER_VIRT或ITIMER_PROF中的一个。

下面是关于setitimer调用的一个简单示范,在该例子中,每隔一秒发出一个SIGALRM,每隔0.5秒发出一个SIGVTALRM信号:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
int sec; 

void sigroutine(int signo) {
switch (signo) {
case SIGALRM:
printf("Catch a signal -- SIGALRM ");
break;
case SIGVTALRM:
printf("Catch a signal -- SIGVTALRM ");
break;
}
return;
} 

int main() {
struct itimerval value,ovalue,value2;
sec = 5; 

printf("process id is %d ",getpid());
signal(SIGALRM, sigroutine);
signal(SIGVTALRM, sigroutine); 

value.it_value.tv_sec = 1;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 1;
value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &value, &ovalue); 

value2.it_value.tv_sec = 0;
value2.it_value.tv_usec = 500000;
value2.it_interval.tv_sec = 0;
value2.it_interval.tv_usec = 500000;
setitimer(ITIMER_VIRTUAL, &value2, &ovalue); 

for (;;) ;
} 

该例子的屏幕拷贝如下: 

localhost:~$ ./timer_test
process id is 579
Catch a signal – SIGVTALRM
Catch a signal – SIGALRM
Catch a signal – SIGVTALRM
Catch a signal – SIGVTALRM
Catch a signal – SIGALRM
Catch a signal –GVTALRM 
作者:AngryFox 分类: Uncategorized April 21st, 2013 暂无评论

linux下kill() 函数的调用:

【kill】函数的功能:向任何进程或进程组发送信号
kill()函数的原型:
#include
#include
int kill(pid_t pid,int signo)

参数:
pid:可能选择有以下四种

1. pid大于零时,pid是信号欲送往的进程的标识。
2. pid等于零时,信号将送往所有与调用kill()的那个进程属同一个使用组的进程。
3. pid等于-1时,信号将送往所有调用进程有权给其发送信号的进程,除了进程1(init)。
4. pid小于-1时,信号将送往以-pid为组标识的进程。

sig:准备发送的信号代码,假如其值为零则没有任何信号送出,但是系统会执行错误检查,通常会利用sig值为零来检验某个进程是否仍在执行。

返回值说明: 成功执行时,返回0。失败返回-1,errno被设为以下的某个值 EINVAL:指定的信号码无效(参数 sig 不合法) EPERM;权限不够无法传送信号给指定进程 ESRCH:参数 pid 所指定的进程或进程组不存在

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>

int main(void)
{
    pid_t childpid;
    int status;
    int retval;

    childpid = fork();
    if(-1 == childpid)
    {
        perror("fork error \n");
        exit(-1);
    }else if(0 == childpid){
        puts("In fork child process");
        sleep(5);
        //exit(1);                                                                                             

    }else{
        if(0 == (waitpid(childpid, &status, WNOHANG)))
        {
            retval = kill(childpid, SIGKILL);

            if(retval)
            {
                puts("kill failed.");
                perror("kill");
                waitpid(childpid, &status, 0);
            }else{
                printf("%d killed \n", childpid);
            }
        }   

    }   

    exit(1);
}

在确信fork调用成功后,子进程睡眠100秒,然后退出。
同时父进程在子进程上调用waitpid函数,但使用了WNOHANG选项(WNOHANG如果没有任何已经结束的子进程则马上返回,不予以等待),
所以调用waitpid后立即返回。父进程接着杀死子进程,如果kill执行失败,
返回-1,否这返回0。如果kill执行失败,父进程第二次调用waitpid,
保证他在子进程退出后再停止执行。否则父进程显示一条成功消息后退出。

作者:AngryFox 分类: Uncategorized April 21st, 2013 暂无评论

在init所有的运行级别中都要执行/etc/rc.d/rc.sysinit脚本。该文件会进一步运行基本系统初始化命令;对文件系统进行全面的检查,以确定本次的启动是否正常。
run once at the boot time
/etc/rc.d/rc.sysinit是一个shell脚本文件,主要完成一下工作:
(1)基本的系统初始化命令:
设置环境变量的命令搜索路径;
读取网络配置设置;
安装内核映像文件系统/proc;
加载键盘映像程序;
加载系统font;
启动系统交换分区;
设置主机名;
设置NIS域名;
(2)检查文件系统:
检查文件系统选项;
检查根文件系统。如果根文件系统有错误,则显示错误信息并重新启动计算机;
检查即插即用设备;
以读写方式重新安装根文件系统;
把内核映像文件系统/proc加到/etc/mtab中;
检查根文件系统的磁盘配额;
把根文件系统和/proc加到/etc/mtab中;
RAID设备处理;
检查一般的文件系统。如果有错误,则显示错误信息并重新启动计算机;
安装所有其他的文件系统;
检查一般文件系统的磁盘配额;
清理/etc目录;
删除UUCP锁定的文件,以释放资源;
删除旧文件系统;
删除PID文件;
删除X锁定;
删除PsctgresSQL套接字;
(3)初始化接口电路:
初始化串口;
如果系统中使用SCSI磁带机,将其装入st模块;
保存开机信息;
执行/etc/rc.d/init.d/random脚本,初始化随机数发生器

作者:AngryFox 分类: Uncategorized April 21st, 2013 暂无评论

iptables的安装、清除iptables规则、iptables只开放指定端口、iptables屏蔽指定ip、ip段及解封、删除已添加的iptables规则等iptables的基本应用。
/etc/sysconfig/iptables

1、安装iptables防火墙
如果没有安装iptables需要先安装,CentOS执行:

yum install iptables
Debian/Ubuntu执行:

apt-get install iptables
2、清除已有iptables规则
iptables -F
iptables -X
iptables -Z
3、开放指定的端口
#允许本地回环接口(即运行本机访问本机)
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
# 允许已建立的或相关连的通行
iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
#允许所有本机向外的访问
iptables -A OUTPUT -j ACCEPT
# 允许访问22端口
iptables -A INPUT -p tcp –dport 22 -j ACCEPT
#允许访问80端口
iptables -A INPUT -p tcp –dport 80 -j ACCEPT
#允许FTP服务的21和20端口
iptables -A INPUT -p tcp –dport 21 -j ACCEPT
iptables -A INPUT -p tcp –dport 20 -j ACCEPT
#如果有其他端口的话,规则也类似,稍微修改上述语句就行
#禁止其他未允许的规则访问
iptables -A INPUT -j REJECT (注意:如果22端口未加入允许规则,SSH链接会直接断开。)
iptables -A FORWARD -j REJECT
4、屏蔽IP
#如果只是想屏蔽IP的话“3、开放指定的端口”可以直接跳过。
#屏蔽单个IP的命令是
iptables -I INPUT -s 123.45.6.7 -j DROP
#封整个段即从123.0.0.1到123.255.255.254的命令
iptables -I INPUT -s 123.0.0.0/8 -j DROP
#封IP段即从123.45.0.1到123.45.255.254的命令
iptables -I INPUT -s 124.45.0.0/16 -j DROP
#封IP段即从123.45.6.1到123.45.6.254的命令是
iptables -I INPUT -s 123.45.6.0/24 -j DROP
4、查看已添加的iptables规则
iptables -L -n
v:显示详细信息,包括每条规则的匹配包数量和匹配字节数
x:在 v 的基础上,禁止自动单位换算(K、M) vps侦探
n:只显示IP地址和端口号,不将ip解析为域名

5、删除已添加的iptables规则
将所有iptables以序号标记显示,执行:

iptables -L -n –line-numbers
比如要删除INPUT里序号为8的规则,执行:

iptables -D INPUT 8
6、iptables的开机启动及规则保存
CentOS上可能会存在安装好iptables后,iptables并不开机自启动,可以执行一下:

chkconfig –level 345 iptables on
将其加入开机启动。

CentOS上可以执行:service iptables save保存规则。

另外更需要注意的是Debian/Ubuntu上iptables是不会保存规则的。

需要按如下步骤进行,让网卡关闭是保存iptables规则,启动时加载iptables规则:

创建/etc/network/if-post-down.d/iptables 文件,添加如下内容:

#!/bin/bash
iptables-save > /etc/iptables.rules
执行:chmod +x /etc/network/if-post-down.d/iptables 添加执行权限。

创建/etc/network/if-pre-up.d/iptables 文件,添加如下内容:

#!/bin/bash
iptables-restore < /etc/iptables.rules
执行:chmod +x /etc/network/if-pre-up.d/iptables 添加执行权限。