Linux学习初记

来源:互联网 发布:剑灵动漫人物捏脸数据 编辑:程序博客网 时间:2024/05/16 13:56

我的第一个shell程序:tt1.sh

while true

do

       date;

       sleep 1;

done

 

执行方式1:sh tt1.sh

执行方式2:./tt1.sh(要求该文件有可执行权限)

 

Shell变量:

环境变量:

       工具:echo 回显

       显示环境变量:echo $HOME

                              echo $HOSTNAME

                              echo $LOGNAME

       修改环境变量:export PATH=/home/ding:$PATH      构建交叉编译工具是用到

 

vi ~/.bashrc

 

/etc/X11/xinit/xinitrc

 

pwd 当前目录

 

共享目录:/mnt/hgfs

 

nfs协议

mount -t nfs 192.168.1.117:/dingyuanpu /mnt/nfs

 

全部删除:rm -f *

 

复制:yy p

 

linux 默认的可执行文件有两种格式:.out .elf(用到最多)

 

gcc的使用:

不加参数时,默认生成a.out的文件

指定文件名:cc -o test test.c

加人调试信息:cc -g -o test test.c

生成中间文件:cc -c test.c

优化选项:-O(更快)和-O2(更小、更快)

调试和剖析:-g和-pg

 

使用GUN  make编辑makefile

使用make,必须编写一个叫做Makefile的文件,这个文件描述了软件包中文件之间的关系,提供更新每个文件的命令。一般在一个软件包里,通常是可执行文件靠目标文件来更新,目标文件靠编译源文件来更新

Makefile写好之后,每次改变了某些源文件,只需要执行make命令

 

GDB调试工具

linux中的GNU调试程序gdb,用来调试c和c++

在编译的时候一定要加人-g选项

 

gdb test

list或l 列出要调试的程序

break或b设置断点

run或r运行

next或n单步运行

watch a 检测监测点a

 

程序运行过程中,哪些变量时存放在堆中,哪些是存放在栈中?

堆:静态变量、全局变量、常数 malloc

栈:子函数的参数、局部变量、返回地址

 

forck(void)函数:

创建子进程

<sys/type.h>

<unistd.h>

该函数调用一次返回两次值,子进程返回的是0,而父进程返回的则是子进程的ID

使用fork函数得到的子进程是从父进程处继承了进程的地址空间

父进程设置的锁,子进程不继承

 

vfork(void)函数

而后fork函数相同,相比之下跟省空间(复制一部分,公用父进  程数据(cow)技术,如在ucLinux中

 

exec函数集

在用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序

当进程调用一种exec函数时,该进程完全由新程序代换,而新程序则冲其main函数开始执行。

 

c语言下只有一种注释方式,//是c++下的,有的编译器不支持,尽量使用标准c下的方式

 

管道:

ps -ef | grep nfsd

 

管道是单向的、先进先出的、无结构的、固定大小的字节流,他吧一个进程的标准输出和另一个进程的标准输入连接在一起。

管道注要用于不同进程之间的同学

 

创建一个简单的管道:int pipe(int fd[2])

创建一个管道之后,一般情况下会产生一个新的进程

fd[0]用于读取管道,fd[1]用于写入管道

 

可以通过打开两个管道来创建一个双向的管道。但需要在子进程中正确的设置文件描述符

必须在系统调用fork()中调用pipe(),否则子进程将不会继承文件描述符。

当使用半双工管道时,任何关联的进程都必须共享一个相关的祖先进程。因为管道存在于系统内核中,所以任何不在创建管道的进程的祖先进程中的进程都将无法寻址它。而在命名管道中却不是这样

 

pipe_pw.c

先创建一个管道,创建管道描述符:pipe_fd[2](读、写)

创建两个进程:父进程和子进程

在父进程中写数据,睡眠3秒钟

在子进程中度数据

 

管道的操作也支持基于文件流的模式

 

FILE *popen(char *command, char *type);

管道中数据的方向由第二个参数type控制。此参数可以是r或w,分别代表读、写

 

int pclose(FILE *stream);

 

命名管道

命名管道是文件系统中作为一个特殊的设备文件而存在的

 

不同祖先的进程之间可以通过管道共享数据

 

int mkfifo(const char *pathname, mode_t mode)

 

在/tmp下有一个myfifo管道,当向管道中写入东西时,管道内容会增加

 

信号通信

 

信号时软件中断

很多条件可以产生一个信号,

用户某些按键产生信号,如ctr+c

硬件异常产生信号,如除数为0

进程用kill(2)函数可以将信号发送给另一个进程或进程租

 

可以要求系统在某个信号出现时进行三种操作:忽略、捕捉、执行系统默认动作

其中SIGKILL和SIGSTOP信号不能忽略

 

对信号的缺省动作有5种:

异常终止(abort):在进程的当前目录下,把进程的地址空间、  寄存器内容保存到一个叫core的文件中,而后终止进程

退出(exit):不产生core文件,直接终止进程

忽略(ignore):忽略该信号

停止(stop):挂起该进程

继续(continue):如果进程被挂起,则恢复进程的运行。否则           忽略信号

 

int kill(pid_t pid, int signo);

int raise(int signo);

 

#include<unistd.h>

unsigned int alarm(unsigned int seconds);

使用此函数可以设置一个时间值(闹钟时间),在将来的某个时间值会被超过,当锁设置的时间被超过后,产生SIGNLRM信号。如果不忽略或不捕捉此信号,则其默认动作时终止改进程

 

#include<unistd.h>

int pause(void);

是调用进程挂起知道捕捉到一个信号

 

#include<signal.h>

void (*signal (int signo, void (*func)(int)))(int)

 

该函数太复杂了,可以使用typedef使其简化

typedef void sign(int);

sign *signal(int, handler *);

 

见范例:mysignal.c

ctr+c发送一个SIGINT信号

ctr+/发送一个SIGOUIT信号

 

信号集函数数组

signal set

 

sigprocmask()这样的函数使用这种数据类型,以告诉内核不允许发生该信号集中的信号。信号集函数组包含:创建函数集、登记信号集、检测信号集

 

创建信号集函数

#include <signal.h>

int sigemptyset(sigset_t * set) ;

int sigfillset(sigset_t * set) ;

int sigaddset(sigset_t * set,int signo) ;

int sigdelset(sigset_t * set,int signo) ;

       四个函数返回:若成功则为0,若出错则为-1

int sigismember(const sigset_t * set, int                    signo) ;

       返回:若真则为1,若假则为0。

 

一个进程的信号屏蔽字可以规定当前阻塞而不能递送给该进程的信号集。调用sigprocmask可以检测或更改进程的信号屏蔽字

#include<signal.h>

Int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

 

#include<signal.h>

Int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);

此函数的功能是检测或修改与指定信号相关联的处理动作。此函数取代了UNIX早期使用的signal函数

 

守护(精灵)进程:

生存期长的一种进程。它们常常在系统引导装入时启动,在系统关闭时终止。因为他们没有控制终端,所有说它们是在后台运行的。

 

ps:查看前台服务

ps-e:查看所有进程

所用的守护进程的父进程都是init进程

 

守护进程编程规则(5步)

1、  创建子进程,父进程退出

2、  调用setsid以创建一个新的会话,并担任该会话组的组长

3、  改变当前目录为根目录chdir(“/”);

4、  重设文件权限掩码umask(0);

5、  关闭不再需要的文件描述符

 

守护进程的出错处理

使用syslog服务,将出错信息输入到/var/log/message系统日志文件中去

 

共享内存

 

共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容

 

共享内存的实现有两个步骤

1、  创建共享内存,使用shmegt函数

2、  映射共享内存,将这段创建的共享内存映射到具体的进程空间去使用shmat函数

 

在一个函数中执行一个shell,system(“lpcs –m”);//显示进程间通信状态

 

消息队列

 

消息队列是一个消息的链表,有“FIFO”的特性,也可以随即查询

 

文件描述符

 

对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,向内核进程返回一个文件描述符。当读写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write

 

可以调用lseek显示地定位一个打开的文件

 

Linux串口应用开发

 

串口通信时计算机常用的接口,如:RS-232-C接口。该标准采用一个DB25芯引脚连接器或DB9芯引脚连接器。

芯片内部常局有UART控制器,其可工作于Interrupt(中断模式)或DMA(直接内存)

 

2接收、3发送、5接地

 

通用异步串行接口(UART)操作主要包含:

数据发送

数据接收

产生中断

产生波特率

Loopback模式

红外模式

自动流控模式

穿孔参数的配置主要包括:波特率、数据位、停止位、流控制协议

 

串口1:/dev/ttyS0

串口2:/dev/ttyS1

 

串口配置流程视频20

 

串口的使用:

打开串口:

fd = open(“/dev/ttyS0”, O_RDWR | O_NOCTTY | O_NDELAY);

恢复串口的状态为阻塞状态,用于等待串口数据的读入

fcntl(fd, F_SETFL, 0);

测试打开的文件描述符是否引用一个终端设备,以进一步确认串口是否打开

isatty(STDIN_FILENO)

……
原创粉丝点击