Linux下父进程定期杀死超时子进程的例子
在Linux下会父进程通过fork()出的子进程可能会由于某种原因死锁或睡眠而无法终止,这时候需要父进程杀死子进程。本程序是父进程检测到子进程运行一段时间后杀死子进程的例子。
父进程的检测代码如下:
1 |
|
子进程调用execv()函数执行的child代码如下:
1 |
|
例子比较简单,不作过多解释。
在Linux下会父进程通过fork()出的子进程可能会由于某种原因死锁或睡眠而无法终止,这时候需要父进程杀死子进程。本程序是父进程检测到子进程运行一段时间后杀死子进程的例子。
父进程的检测代码如下:
1 | #include <stdio.h> |
子进程调用execv()函数执行的child代码如下:
1 | #include <stdio.h> |
例子比较简单,不作过多解释。
在外地出差,趁着午休时间躺在机房走廊的地板上想小憩一会却怎么也进入不了状态。突然写着可以写写我心中目前的理想工作状态。随着年龄、阅历和知识水平的增长,每个人心中理想的工作状态也会在变。我现在的理想工作状态跟我刚毕业时肯定是有区别的,刚毕业那会初入茅庐,对公司的很多事情还是懵懂,自然期望找个高手带一带。
我期望加入一家技术为王的公司。
技术才是科技公司真正的核心竞争力,而非销售和公关能力。从硅谷中做大做强的公司哪个不是以技术作为领先竞争对手的筹码,十几年前的google的崛起、雅虎的衰落,近几年Github的火爆无不是技术因素在其决定作用。在中国软件行业还未发展成熟,觉大多数企业仍然在以销售为核心盈利方式的畸形发展方式中,但技术为王绝对是个趋势,这个不是靠关系靠政策可以改变的事实,这个是大势所趋、历史必然。
我不奢望技术为王的公司中牛人辈出但是期望能多几个牛人就多几个牛人,至少不期望在公司中见到一看就没有做技术潜质的同事(一个人适不适合做技术有时候是可以看出来的)。
我期望加入一家互联网行业的公司。
软件行业按照产品类型大致可以分三类:外包、卖产品和做平台。
外包公司完全以订单为导向,往往涉及到复杂的业务逻辑,技术含量低,自然不在我的考虑范围内。
我之前从事的公司都是在卖产品的公司,往往卖产品的公司需要有一定的技术含量,但是技术不能决定公司发展,这一类公司是以销售为导向的公司,一套产品往往可以卖上多年,甚至十几年也不奇怪。
做平台的公司往往不需要过多的销售,大多数是以用户量为王的,而要想拉拢用户到平台上往往需要靠技术或销售取胜,而技术因素相对更加关键。以Dota对战平台为例,前几年比较火爆的是浩方和VS,现在成了11对战平台的天下了。11对战平台后来者居上就是因为11对战平台率先推出了天梯模式和路人模式,从而落下了竞争对手一大截。互联网行业属于第三类,而济南几乎找不到这类公司。就算有一些这样的公司,往往也是以销售为导向的公司。韩都衣舍也有自己的网站,但是流量应该没有淘宝大,估计网站技术上的投入也一般般。银座集团在电商火爆了后也搞了个网上商城,单从界面看可跟苏宁拉在同一个档次,但效果如何影响怎么样可想而知,估计技术都是外包的,仅是领导拍拍脑袋的产物。我实在想不到在济南有什么互联网公司了,如果你知道请告诉我。
我期望加入一家创业型的公司。
我现在还不具备单独创业的实力,但我一直梦想能够加入一家有梦想有激情的创业公司。加入创业公司就意味着不会清闲,我只期望每天能够过的充实并快乐着。《黑客与画家》中提到快速致富的手段就是加入一家创业公司,在美国如此,在中国亦如此。
总结一下,我想加入一家技术为王的互联网行业的创业公司。如果你知道在济南有哪家公司可以满足我的要求,请告诉我,谢谢!
本实验为在虚拟机环境中实验,操作系统为Red Hat Enterprise6.0 32位,当前网卡列表如下:
1 | [root@localhost ~]# ifconfig |
目的为将网卡eth1更改为eth0,将eth2更改为eth3。
在文件中内核启动时增加_biosdevname=0_选项。修改后的文件内容如下:
1 | default=0 |
在/etc/sysconfig/network-scripts目录中将原有的网卡配置文件ifcfg_Auto_eth1和ifcfg_Auto_eth2更改为ifcfg_eth0和ifcfg_eth3,同时修改文件的内容,将文件的内容中的网卡设备名称进行替换。替换后的文件ifcfg_eth0内容如下:
1 | TYPE=Ethernet |
该文件存在于/etc/udev/rules.d目录下。该文件如果不存在,开始时会自动创建,里面包含了网卡名称的配置信息。
在修改完上述内容后重新启动机器配置就修改过来了,修改完成之后的网卡配置如下:
1 | [root@localhost rules.d]# ifconfig |
[TOC]
# 安装kdevelop
确保可以上网,这里采用yum的安装方式进行安装。
首先执行命令:yum install kdevelop,会出现如下提示:
1 | Loaded plugins: rhnplugin, security |
出现上述错误是由于redhat没有注册,所有不能使用它自身的源进行更新,可以更换为CentOS系统的源进行更新,操作步骤为:
1、进入/etc/yum.repos.d/目录。在命令行输入:wget http://docs.linuxtone.org/soft/lemp/CentOS-Base.repo。
2、ls 一下,会看到一个文件名为CentOS-Base.repo的文件。
3、将原来的文件rhel-debuginfo.repo改名为rhel-debuginfo.repo.bak。
4、将CentOS-Base.repo改名为rhel-debuginfo.repo
再次运行命令:yum install kdevelop,就可以安装kdevelop了。
安装过程中遇到了需要的pcre包无法从centos的源中下载的问题,解决方法为根据yum命令无法下载的包,在google中搜索,下载包然后再redhat上用rpm的升级命令来安装。具体下载网址为:电子科技大学星辰工作室开源镜像服务。
rpm相关命令:
安装一个包:rpm -ivh
升级一个包:rpm -Uvh
移走一个包:rpm -e
安装上kdevelop后在执行程序的时候会提示/bin/sh:konsole:command not found
。执行yum install kdebase
命令来安装konsole。
修改ssh服务的配置文件/etc/ssh/sshd_config文件,将文件中的#PasswordAuthentication yes注释打开。
修改ssh服务的配置文件/etc/ssh/sshd_config文件,将文件中的PermitRootLogin no更改为yes。这样即可以用ssh工具连接到该机器。
该部分参考文档的网址为:http://blog.csdn.net/gltyi99/article/details/6141972
修改/usr/share/gdm/defaults.conf文件的权限,默认权限为444,chmod 700 /usr/share/gdm/defaults.conf。
在/usr/share/gdm/defaults.conf文件的末尾添加如下内容:
1 | Enable=true |
修改/etc/gdm/custom.conf文件
1 | [xdmcp] |
修改/etc/inittab文件,不修改原来的设置,在文件的最后增加一行:
1 | x:5:respawn:/usr/sbin/gdm |
修改/usr/share/gdm/defaults.conf文件,将其中的
1 | [security] |
AllowRemoteRoot=false更改为AllowRemoteRoot=true。
修改/etc/securetty文件,在文件底部添加如下内容:
1 | pts/0 |
修改/etc/pam.d/login文件,将其中的一行注释
1 | #auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so |
修改/etc/pam.d/remote,将其中的一行注释
1 | #auth required pam_securetty.so |
修改/etc/xinetd.d/krb5-telnet文件,将文件内容由
1 | service telnet |
更改为:
1 | service telnet |
同样将/etc/xinetd.d/ekrb5-telnet文件中的disable=yes更改为disable=no。
为了阅读代码方便,安装字体。
可以通过locale命令来查看操作系统编码。输出如下:
1 | LANG=zh_CN.UTF-8 |
打开/etc/sysconfig/i18n文件,文件默认内容为:
1 | LANG="zh_CN.UTF-8" |
将文件内容修改为:
1 | LANG="zh_CN.GBK" |
声明将一个名字引入到了程序中,;定义提供了一个实体(如类型、实例、函数)在程序中的唯一描述,为变量分配存储空间;
在一个给定的作用于中重复一个给定的声明是合法的,而重复定义是非法的。声明仅对当前编译单元有效,仅会在.o文件中加入了一个未定义符号。特定的类型不必与实际的定义类型匹配。
内部链接和外部链接是根据链接过程中一个符号是在编译单元内部还是外部进行划分的,编译单元是按照一个.c或.cpp文件的作用域进行划分的。
内部链接:一个标识符对于编译单元(一个目标文件)来说是局部的,并在链接时与其他编译单元中的标识符不冲突。
内部链接包括:
外部链接:在多文件程序中,链接时这个标识符可以和其他编译单元交互。这些外部符号在程序中必须是唯一的,用来被其他编译单元中未定义的符号访问。
将带有外部链接的定义放在头文件中是错误的。
外部链接包括:
test1.h内容如下:
1 | void print1(); |
test1.cpp内容如下:
1 | #include <stdio.h> |
test2.h内容如下:
1 | void print2(); |
test2.cpp内容如下:
1 | #include <stdio.h> |
main.cpp内容如下:
1 | #include <stdio.h> |
从实例可以看出在全局作用域内声明的const类型的变量为内部链接的,在多个文件的作用域中分别定义相同的const类型的变量并不会产生冲突。
直接访问类的数据成员违反了面向对象中的封装原则,应该将类的数据成员私有化,并提供接口供部访问,类似于java bean规范。
避免使用全局变量,应该将全局变量封装到类中,并提供接口供外部访问。
为避免命名冲突,将全局函数封装到类中。
避免在头文件的作用域中使用enum、typedef和const数据,应该将这些数据封装到头文件的类作用域中。
在头文件中只应该包含如下内容:类、结构体、联合体和运算符函数的声明,类、结构体、联合体和内联函数的定义。
本文为Linux设备驱动程序的入门实践文章,编写一个hello world程序,并在Linux上执行。
驱动程序hello.c文件内容如下:
1 | #ifndef __KERNEL__ |
Makefile文件的写法可以采用传统的make方式,也可以采用kbuild的方式。
采用传统的make方式的写法如下:
1 | ifeq ($(KERNELRELEASE),) |
采用kbuild方式的Makefile内容如下:
1 | obj-m := hello.o |
将hello.c和Makefile文件放在任意目录中,执行make命令编译。
执行insmod hello.ko
命令安装驱动程序,通过lsmod
命令即可看到驱动程序已经安装。
通过查看/var/log/messages文件即可看到hello驱动程序打印的内容。
执行rmmod hello.ko
命令即可卸载驱动程序模块。
《深入理解Linux设备驱动程序》
《Linux那些事之我是USB》
Ubuntu12.10 内核源码外编译 linux模块–编译驱动模块的基本方法
本文仅为了练习Linux内核源码的编译安装,安装环境为VMWare下的CentOS,现有CentOS版本为2.6.32-358.el6.x86_64
。
/boot/grub/grub.conf文件内容如下:
1 | # 注释部分去掉 |
首先从Linux的官方网站下载最新版内核Linux3.13。
执行tar Jxvf linux-3.13.tar.xz -C/usr/src/kernels
命令将内核源码解压到内核源代码存放目录/usr/src/kernels/,该源码目录并不固定,但推荐将内核源码存放到该目录下。
为了将上次编译时的目标文件及相关设置文件删除,执行make mrproper
。
可以采用了多种方式,这里采用make menuconfig
的方式来挑选内核功能,该方式不需要X Window(make xconfig
方式)的支持,而且要比纯命令行方式(make config
)要直观。执行make menuconfig
遇到如下错误:
1 | [root@localhost linux-3.13]# make menuconfig |
这是因为需要ncurses库的支持,下面采用从源码安装的方式安装ncurses。
从ncurses的官方网站下载最新版的ncurses-5.9.tar.gz。然后分别执行./configure
、make、
make install`命令安装。
为了能够在编译完成后的内核版本中通过uname -r
看到定义的内核版本号,修改Makefile文件。其中EXTRAVERSION
字段值为空,将其赋值为kuring。
执行make
命令,该过程需要话费很长时间,我在512MB的VM下跑,花费了大约1个半小时时间。
执行make modules
命令。
执行make modules_install
命令,会将内核模块安装到/lib/modules目录下。
执行make install
命令,产生如下输出:
1 | sh /usr/src/kernels/linux-3.13/arch/x86/boot/install.sh 3.13.0kuring arch/x86/boot/bzImage \ |
这个错误跟vmware的vmware tools有关,暂时不去管。
这样再去看/boot/grub/grub.conf文件,会看到文件已经变化,已经将新内核添加到开机启动项中。
1 | # 注释部分去掉 |
同时在/boot目录下已经多出了vmlinuz-3.13.0kuring、System.map-3.13.0kuring、initramfs-3.13.0kuring.img文件。
重启系统后,在启动菜单中多出了新内核选项。进入新内核后,执行uname -r
显示3.13.0kuring
,说明新内核已经安装完成。
从官方网站下载最新的viplugin插件:viPlugin_2.12.0。
将viPlugin_2.12.0.zip文件解压到eclipse安装目录下的dropins目录下。
该插件为收费插件,在eclipse安装的根目录下新建viPlugin2.lic文件,文件内容为:_q1MHdGlxh7nCyn_FpHaVazxTdn1tajjeIABlcgJBc20
_。
重启eclipse后即可生效。
官方参考文档地址:http://www.viplugin.com/files/User_Manual_viPlugin.pdf
相关下载:viPlugin_2.12.0.zip
在用CentOS默认的svn客户端工具访问Windows下搭建的subversion时会提示如下错误:
1 | [kuring@localhost 桌面]$ svn checkout https://192.168.100.100/svn/test |
通过执行如下命令可以看到svn是支持https协议的:
1 | [kuring@localhost ~]$ svn --version |
这是由于svn客户端在https协议中使用了GnuTLS库造成的,将其更改为使用openssl库即可。通过执行如下命令可以查看svn使用的库:
1 | [kuring@localhost bin]$ ldd svn | grep ssl |
下面选择重新编译的方式来安装svn。
执行:yum remove subversion
这里已经安装:
1 | [kuring@localhost tmp]$ rpm -qa | grep openssl |
这里选择的安装版本为0.29.6,subversion对neon的版本有要求。如果不是subversion的版本,在执行subversion下的configure文件时并不会报错
1 | [kuring@localhost software]$ tar zvxf neon-0.29.6.tar.gz |
1 | tar zvxf apr-1.5.0.tar.gz |
1 | tar zvxf apr-util-1.5.3.tar.gz |
1 | unzip sqlite-amalgamation-3080401.zip |
1 | tar zvxf subversion-1.7.16.tar.gz |
然后再执行svn --version
命令可以看到已经包含了https协议。
SSL handshake failed: SSL error: Key usage violation in certificate has been detected CentOS
[TOC]
在Linux操作系统中,每个文件都有一组9个权限位来控制谁能够读写和执行该文件的内容。这组权限对于文件的意义非常容易理解。但是对于目录而言就不是那么容易理解了。要想搞明白权限机制需要了解文件系统中的inode节点和block等概念,并大致了解文件系统的内部实现原理。
这部分比较容易理解。比较容易搞错的为:
w位:包含对文件的添加、修改该文件内容的权限,但不包含删除文件或移动该文件的权限,因为文件的文件名信息存储在父目录的block中,而不是在该文件的inode节点中。父目录的block中包含该文件的inode节点和文件名信息,通过父目录中的inode节点找到该文件。
r位:表示具有读取该目录列表的权限。
w位:对该文件夹下创建新的文件或目录进行增加、删除、修改操作。
x位:这个稍微难以理解。表示用户能否进入该目录成为工作目录,即是否可以cd到该目录。通常和r位组合一块使用。
假设root用户对testing目录和testing目录下的testing文件拥有的如下权限:
1 | [root@localhost tmp]# ls -ald testing/ testing/testing |
kuring用户拥有对该文件夹的读权限,但是没有x权限。当kuring用户访问时会提示如下内容:
1 | // 拥有r的权限可以查询文件名,但是没有x权限,不能读取除文件名外的其他信息,产生了问号。 |
在上述例子中,给kuring用户增加对目录testing的rwx权限,却只拥有testing目录下的testing文件的r权限。权限情况如下所示:
1 | [kuring@localhost tmp]$ ls -ald testing testing/testing |
kuring用户执行如下操作:
1 | // 当对文件进行更改时由于没有对文件的w权限,操作失败 |
只有了解了原理,就可以理解在多级目录并且目录的权限不一致的情况下相应的权限问题了。
要讲解set uid和set gid,就涉及到进程的用户ID概念。用户ID又可以分为两部分:
实际用户ID和实际组ID:标识了究竟是哪个用户执行了该程序,跟命令行中的登录用户一致,可以通过id命令查看。
有效用户ID和有效组ID:系统通过有效用户ID、有效组ID和附加组ID来决定进行对系统资源的访问权限。在Linux系统中一个用户可以属于多个组,在/etc/passwd文件中一个用户仅能标识出隶属于一个组ID,该组ID叫做默认的组ID。在/etc/group为文件中可以标识出一个用户隶属于多个组,这多个组中除去默认的组ID叫做附加组ID。
以/usr/bin/passwd命令为例,该程序的权限为:rwsr-xr-x。普通用户可以调用该程序修改自己的密码,而密码文件/etc/shadow未设置任何权限,即只有root用户可以操作该文件。
1 | [root@localhost tmp]# ll /usr/bin/passwd |
passwd文件的s标志表明setuid位被设置。
passwd的拥有者为root;当普通用户执行passwd命令时,普通用户具有该命令的执行权限;passwd执行该命令时会暂时获得root用户权限;/etc/shadow就可以被修改。
也许看到这里就会有疑问:那岂不是普通用户可以通过/etc/passwd命令修改其他用户的密码了。之所以不可以这么操作是因为passwd命令内部通过逻辑实现。
设置在文件上的情况:
设置在目录上的情况:
该权限位仅对目录有效,如果在目录上设置了粘附位,只有该目录的属主、该文件的属主或root用户可以删除或重命名该目录文件。
/tmp文件夹的权限如下,其中的t位表示粘附位:
1 | [kuring@localhost /]$ ll -ad tmp/ |
如果在/tmp下kuring用户创建了自己的文件kuring_file,并设置权限为777,test用户并不能删除该文件
1 | [kuring@localhost tmp]$ touch kuring_file |
如果设置了setuid位,属主的执行权限中的x用s来代替;
如果设置了setgid位,组执行权限中的x用s来代替;
如果设置了sticky位,权限最后的那个字符被设置为t;
如果设置了setuid、setgid或sticky位中一个,又没有设置相应的执行位,这些位显示为S或T。
4为setuid位,2为setgid位,1为sticky位。具体参考《鸟哥的Linux私房菜》。
《鸟哥的Linux私房菜》
《UNIX/Linux系统管理技术手册》