linux小知识

exec()与system()的区别

执行exec()后,老的进程上下文将被exec出来的新的进程上下文覆盖,新进程代替原进程执行。

执行system()后则相当于fork()出一个子进程,并等待此子进程执行完毕。


我已经找到把系统jiffies变量映射到应用程序空间的方法。

1、到/boot目录下找到内核启动的映像符号表文件。如:System.map-2.6.15-1.2054_FC5smp
2、打开映像符号表文件,找到jiffies变量的偏移地址。格式为:c03bdc00 D jiffies
3、读取偏移值(0xc03bdc00)到变量offset,offset -= 0xc0000000;
4、fd = ::open("/dev/mem", O_RDONLY);
5、p = ::mmap(0, 0x10000, PROT_READ, MAP_SHARED, fd, (off_t)(offset - offset%0x10000));
6、volatile unsigned long* pJiffies = (volatile unsigned long*)((char*)p + offset%0x10000);
以后就可以用*pJiffies来读取jiffies值了。


linux目录里面的头文件用于内核,sys目录里面的头文件用于应用程序或者glibc标准库

export PATH=$PATH:/home/freescale-2010.09/bin
powerpc-linux-gnu-gcc

Linux + Eclipse 配置交叉编译环境
选择C/C++ Build->Settings。在Tool Settings标签栏里面选择Cross Settings。之后在Prefix里面填入形如powerpc-linux-gnu-的前缀,再在Path里面填上Tool Chain的路径,就OK了!
http://www.cnblogs.com/lazygunner/archive/2011/11/30/2269726.html


Windows 下基于 Eclipse 的可视化远程 Linux C/C++ 开发环境搭建
nohup eclipse > /dev/null &
http://blog.csdn.net/lostaway/article/details/8086056


1.linux 包含  # include <strings.h>  ------ vxworks #include <string.h>

2.linux 保护 include <sys/time.h>   ------vxworks没有

 struct timeval
{
time_t tv_sec; /* Seconds.  */
time_t tv_usec; /* Microseconds.  */
};

gettimeofday

3.VxWorksWindows上,EAGAIN的名字叫做EWOULDBLOCK


4.普通用户无法绑定1-1024端口,ROOT用户才有该权限


5. 虚拟机的linux用的X86(因此小端),vxworks用MPC852(因此大端)


6. linux线程都是进程模拟的,ps命令默认这些模拟进程是不显示的。

linux多线程环境下gettid() pthread_self() 两个函数都获得线程ID,可它们的返回值不一样。
linux使用进程模拟线程,gettid 函数返回实际的进程ID(内核中的线程的ID).
pthread_self 函数返回 pthread_create创建线程时的ID(POSIX thread ID).

pthread_self返回的是同一个进程中各个线程之间的标识号,对于这个进程内是唯一的,而不同进程中,每个线程返回的pthread_self可能返回的是一样的。


查看进程pid
(1) ps ux | grep prog_name
(2) pgrep prog_name 
查看线程tid
(1) ps -efL | grep prog_name
(2) ls /proc/pid/task


下面说下使用命令查看thread ID。


# pgrep test   /*test为正在运行的application*/


45            /*此为进程PID也即主线程ID,二者相同*/


所有进程PID都能在/proc下看到,ls /proc 的话,所有数字都代表一个进程,下一步


# ls /proc/45/task/   
45  46  47  48  49  /* ok 该进程下的所有thread  ID都展现在我们眼前了*/


7. 设备号查看

cat /proc/devices  ---- 查看主设备号

ls -l /dev/   --- 查看设备(包括主,从设备号)


8.inittab脚本
id:runlevel:action:process

action
表示进入对应的runlevel时,init应该运行process字段的命令的方式,有效的action值如下。
boot:只有在引导过程中,才执行该进程,但不等待该进程的结束。当该进程死亡时,也不重新启动该进程。
bootwait:只有在引导过程中,才执行该进程,并等待进程的结束。当该进程死亡时,也不重新启动该进程。实际上,只有在系统被引导后,并从单用户模式进入多用户模式时,这些登记项才被处理;如果系统的默认运行级设置为2(即多用户模式),那么这些登记项在系统引导后将马上被处理。
initdefault:指定系统的默认运行级。系统启动时,init将首先查找该登记项,如果存在,init将依据此决定系统最初要进入的运行级。具体来说,init将指定登记项"run_level"字段中的最大数字(即最高运行级)为当前系统的默认运行级;如果该字段为空,那么将其解释为"0123456",并以"6"作为默认运行级。如果不存在该登记项,那么init将要求用户在系统启动时指定一个最初的运行级。
off:如果相应的进程正在运行,那么就发出一个告警信号,等待20秒后,再通过关闭信号强行终止该进程。如果相应的进程并不存在,那么就忽略该登记项。
once:启动相应的进程,但不等待该进程结束便继续处理/etc/inittab文件中的下一个登记项;当该进程终止时,init也不重新启动该进程。在从一个运行级进入另一个运行级时,如果相应的进程仍然在运行,那么init就不重新启动该进程。
ondemand:与"respawn"的功能完全相同,但只用于运行级为a、b或c的登记项。
powerfail:只在init接收到电源失败信号时,才执行该进程,但不等待该进程结束。
powerwait:只在init接收到电源失败信号时,才执行该进程,并在继续对/etc/inittab文件进行任何处理前等待该进程结束。
respawn:如果相应的进程还不存在,那么init就启动该进程,同时不等待该进程的结束就继续扫描/etc/inittab文件;当该进程终止时,init将重新启动该进程。如果相应的进程已经存在,那么init将忽略该登记项并继续扫描/etc/inittab文件。
sysinit:只有在启动或重新启动系统并首先进入单用户模式时,init才执行这些登记项。而在系统从运行级1~6进入单用户模式时,init并不执行这些登记项。"action"字段为"sysinit"的登记项在"run_level"字段不指定任何运行级。
wait:启动进程并等待其结束,然后再处理/etc/inittab文件中的下一个登记项。
ctrlaltdel:用户在控制台键盘上按下Ctrl+Alt+Del组合键时,允许init重新启动系统。注意,如果该系统放在一个公共场所,系统管理员可将Ctrl+Alt+Del组合键配置为其他行为,比如忽略等


9.默认动态库搜索路径: /lib  /usr/lib  ;默认可执行文件搜索路径:PATH  /usr/local/bin(sbin)   /usr/bin(sbin)   /bin(sbin)


10.Shell 中环境变量的作用域

1、执行脚本时是在一个子shell环境运行的,脚本执行完后该子shell自动退出;

2、一个shell中的系统环境变量会被复制到子shell中(用export定义的变量);

3、一个shell中的系统环境变量只对该shell或者它的子shell有效,该shell结束时变量消失
(并不能返回到父shell中)。

3、不用export定义的变量只对该shell有效,对子shell也是无效的。


11.Linux 开机脚本启动顺序: 
第一步:启动内核
第二步:执行init (配置文件/etc/inittab)
第三步:启动相应的脚本,执行inittab脚本,并且执行里面的脚本/etc/init.d rc.sysinit rc.d rc.local。。。
第四步:启动login登录界面 login
第五步:在用户登录的时候执行sh脚本的顺序:每次登录的时候都会完全执行的 /etc/profile /etc/bashrc /root/.bashrc /root/.bash_profile


12.优先级:(查看 /proc/id/stat)
1.进程优先级(通常所说的优先级指的是动态优先级prio),范围0-139 ,其中0~99是给实时进程使用的,100-139是非实时进程。
2.(nice值的-20~19正好可以映射到100到139这个范围内),因此nice应用于非实时进程。
3.优先级分为三种:静态优先级,动态优先级,实时优先级。


(1)静态优先级:static priority:之所以称为静态优先级是因为它不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改。静态优先级用进程描述符中的static_prio表示。它与nice的关系:static_prio= MAX_RT_PRIO + nice + 20    (MAX_RT_PRIO=100)


(2)动态优先级(prio):调度程序通过增加或减少进程静态优先级的值来奖励IO小号型进程或惩罚cpu消耗型进程。调整后的优先级称为动态优先级。在进程描述符中用 prio表示,通常所说的优先级指的是动态优先级。在 0~MAX_PRIO-1 之间取值(MAX_PRIO 定义为 140),其中 0~MAX_RT_PRIO-1 (MAX_RT_PRIO 定义为100)属于实时进程范围,MAX_RT_PRIO~MX_PRIO-1属于非实时进程。数值越大,表示进程优先级越小。
普通进程的优先级通过一个关于静态优先级和进程交互性函数关系计算得到。随实际任务的实际运行情况得到。实时优先级和它的实时优先级成线性,不随进程的运行而改变。


(3)实时优先级:实时优先级只对实时进程有意义。在进程描述符rt_priority中。取值0~MAX_RT_PRIO-1。 prio=MAX_RT_PRIO-1 – rt_priority 


对于非实时任务,prio =  通过进程的静态优先级和进程的调度策略进行计算 =  调度策略 +(-) static_prio
对于实时任务 prio = MAX_RT_PRIO – 1 – rt_priority



13.进程调度
实时任务(进程或线程):SCHED_FIFO实时调度策略,先到先服务;SCHED_RR实时调度策略,时间片轮转 
非实时任务(进程或线程):SCHED_OTHER 分时调度策略

1,RR调度和FIFO调度的进程属于实时进程,以分时调度的进程是非实时进程。
2,当实时进程准备就绪后,如果当前cpu正在运行非实时进程,则实时进程立即抢占非实时进程。
3,RR进程和FIFO进程都采用实时优先级做为调度的权值标准,RR是FIFO的一个延伸。FIFO时,如果两个进程的优先级一样,则这两个优先级一样的进程具体执行哪一个是由其在队列中的未知决定的,这样导致一些不公正性(优先级是一样的,为什么要让你一直运行?),如果将两个优先级一样的任务的调度策略都设为RR,则保证了这两个任务可以循环执行,保证了公平。


14.error 和 strerror()的使用:
经常在调用linux 系统api 的时候会出现一些错误,比方说使用open() write() creat()之类的函数有些时候会返回-1,也就是调用失败,这个时候往往需要知道失败的原因。这个时候使用errno这个全局变量就相当有用了,strerror()来自己翻译


15.assert断言屏蔽方法:
在Linux下,必须要在编译命令中加入-DNDEBUG中,系统编译时才不会将assert编译进去。不然,程序运行时有可能会被assert中断。


16.system()和execve()区别

system是用shell来调用程序=fork+exec+waitpid,而exec是直接让你的程序代替用来的程序运行。
system 是在单独的进程中执行命令,完了还会回到你的程序中。而exec函数是直接在你的进程中执行新的程序,新的程序会把你的程序覆盖,除非调用出错,否则你再也回不到exec后面的代码,就是说你的程序就变成了exec调用的那个程序了。


17。标准输出重定位 dup函数或dup2函数


18. 内核线程是直接由内核来启动的进程,通常也称为守护进程,”ps”命令查看系统中的进程,这时会发现很多以”[xxxxd]”结尾的进程名,这些进程就是内核线程


19.shell ,export , source命令

1、执行脚本时是在一个子shell环境运行的,脚本执行完后该子shell自动退出;

2、一个shell中的系统环境变量会被复制到子shell中(用export定义的变量);

3、一个shell中的系统环境变量只对该shell或者它的子shell有效,该shell结束时变量消失
(并不能返回到父shell中)。

3、不用export定义的变量只对该shell有效,对子shell也是无效的。

为什么一个脚本直接执行和用source执行不一样

直接执行一个脚本文件是在一个新的子shell中运行的,而source则是在当前shell环境中运行的


双网卡同网段解决方案  --两个网卡的IP属与同一个子网,那么后面这个网卡的IP将自动路由到前面一个网卡上
例如两个IP为192.168.1.100,192.168.1.90 子网掩码为255.255.255.0


ip route add 192.168.1.0/24 dev eth1 src 192.168.1.100 table 10
ip route add default via 192.168.1.1 table 10
ip route add 192.168.1.0/24 dev eth2 src 192.168.1.90 table 20
ip route add default via 192.168.1.1 table 20
ip route add default via 192.168.1.1
ip rule add from 192.168.1.100 table 10
ip rule add from 192.168.1.90 table 20
ip route flush cache


从上面可以看出VmRSS才是我们最关心的内存大小,即

正在使用的物理内存的大小;

而VmSize是进程所拥有的虚拟空间的大小;

“当进程开始使用 已经申请的但还没有用的内存时,

VmRSS的值开始增大,但是VmSize保持不变。”

我们之所以看到许多内存的值的大小超过了内存的总的大小

是因为这里显示的都是虚拟内存的大小,而不是实际的占用的大小;


使能linux驱动中的dev_dbg
1、打开调试开关:你调试的文件中必然包含了<linux/device.h>,或者《linux /paltforam_device.h》,后者包含了前者,在包含此头文件之前,使用#define DEBUG 1 来打开调试开关:例如 
  #include <linux/module.h> 
  #define DEBUG    1 
  #include <linux/platform_device.h> 
  2、修改文件kernel/printk.c文件 
  #define DEFAULT_CONSOLE_LOGLEVEL 8 /* anything MORE serious than KERN_DEBUG */ 
   其中DEFAULT_CONSOLE_LOGLEVEL 为终端console输出的最低级别,比这严重的都将输出。原来该值为7,则调试信息无法输出,修改为8则全部有输出。

make带参数
在makefile文件中可以预先使用一个未定义的变量,在执行make时再传递值
ifeq ($(dbg),1)
      NVCCFLAGS += -g -G
      TARGET := debug
else
      TARGET := release
endif
执行
make dbg=1
就会编译中添加-g -G的debug信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值