ARM的嵌入式Linux移植体验之应用实例
inux所专有,在所有提供了TCP/IP协议栈的操作系统中几乎都提供了socket,而所有这样操作系统,对套接字的编程方法几乎是完全一样的。管道分为有名管道和无名管道,无名管道只能用于亲属进程之间的通信,而有名管道则可用于无亲属关系的进程之间;消息队列用于运行于同一台机器上的进程间通信,与管道相似;共享内存通常由一个进程创建,其余进程对这块内存区进行读写;信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。
下面是一个使用信号量的例子,该程序创建一个特定的IPC结构的关键字和一个信号量,建立此信号量的索引,修改索引指向的信号量的值,最后清除信号量:
#include
#include
#include
#include
voidmain()
{
key_tunique_key;/*定义一个IPC关键字*/
intid;
structsembuflock_it;
unionsemunoptions;
inti;
unique_key=ftok(.,'a');/*生成关键字,字符'a'是一个随机种子*/
/*创建一个新的信号量集合*/
id=semget(unique_key,1,IPC_CREAT|IPC_EXCL|0666);
printf(semaphoreid=%dn,id);
options.val=1;/*设置变量值*/
semctl(id,0,SETVAL,options);/*设置索引0的信号量*/
/*打印出信号量的值*/
i=semctl(id,0,GETVAL,0);
printf(valueofsemaphoreatindex0is%dn,i);
/*下面重新设置信号量*/
lock_it.sem_num=0;/*设置哪个信号量*/
lock_it.sem_op=-1;/*定义操作*/
lock_it.sem_flg=IPC_NOWAIT;/*操作方式*/
if(semop(id,lock_it,1)==-1)
{
printf(cannotlocksemaphore.n);
exit(1);
}
i=semctl(id,0,GETVAL,0);
printf(valueofsemaphoreatindex0is%dn,i);
/*清除信号量*/
semctl(id,0,IPC_RMID,0);
}
2.进程控制/通信编程进程控制中主要涉及到进程的创建、睡眠和退出等,在Linux中主要提供了fork、exec、clone的进程创建方法,sleep的进程睡眠和exit的进程退出调用,另外Linux还提供了父进程等待子进程结束的系统调用wait。
fork
对于没有接触过Unix/Linux操作系统的人来说,fork是最难理解的概念之一,因为它执行一次却返回两个值,以前闻所未闻。先看下面的程序:
intmain()
{
inti;
if(fork()==0)
{
for(i=1;i3;i++)
printf(Thisischildprocessn);
}
else
{
for(i=1;i3;i++)
printf(Thisisparentprocessn);
}
}
执行结果为:
Thisischildprocess
Thisischildprocess
Thisisparentprocess
Thisisparentprocess
fork在英文中是分叉的意思,一个进程在运行中,如果使用了fork,就产生了另一个进程,于是进程就分叉了。当前进程为父进程,通过fork()会产生一个子进程。对于父进程,fork函数返回子程序的进程号而对于子程序,fork函数则返回零,这就是一个函数返回两次的本质。
exec
在Linux中可使用exec函数族,包含多个函数(execl、execlp、execle、execv、execve和execvp),被用于启动一个指定路径和文件名的进程。exec函数族的特点体现在:某进程一旦调用了exec类函数,正在执行的程序就被干掉了,系统把代码段替换成新的程序(由exec类函数执行)的代码,并且原有的数据段和堆栈段也被废弃,新的数据段与堆栈段被分配,但是进程号却被保留。也就是说,exec执行的结果为:系统认为正在执行的还是原先的进程,但是进程对应的程序被替换了。
fork函数可以创建一个子进程而当前进程不死,如果我们在fork的子进程中调用exec函数族就可以实现既让父进程的代码执行又启动一个新的指定进程,这很好。fork和exec的搭配巧妙地解决了程序启动另一程序的执行但自己仍继续运行的问题,请看下面的例子:
charcommand[MAX_CMD_LEN];
voidmain()
{
intrtn;/*子进程的返回数值*/
while(1)
{
/*从终端读取要执行的命令*/
printf(>);
fgets(command,MAX_CMD_LEN,stdin);
command[strlen(command)-1]=0;
if(fork()==0)
{
/*子进程执行此命令*/
execlp(command,command);
/*如果exec函数返回,表明没有正常执行命令,打印错误信息*/
perror(command);
exit(errorno);
}
else
{
/*父进程,等待子进程结束,并打印子进程的返回值*/
wait(rtn);
printf(childprocessreturn%dn,rtn);
}
}
}
这个函数实现了一个shell的功能,它读取用户输入的进程名和参数,并启动对应的进程。
clone
clone是Linux2.0以后才具备的新功能,它较fork更强(可认为fork是clone要实现的一部分),可以使得创建的子进程共享父进程的资源,并且要使用此函数必须在编译内核时设置clone_actually_works_ok选项。
clone函数的原型为:
intclone(int(*fn)(void*),void*child_stack,intflags,void*arg);
此函数返回创建进程的PID,函数中的flags标志用于设置创建子进程时的相关选项。
来看下
应用 实例 体验 移植 嵌入式 Linux ARM 相关文章:
- 数字信号处理(DSP)应用系统中的低功耗设计(05-02)
- SHARC引领第四代通用DSP高端应用潮流(09-27)
- 在应用可编程测控网络设计(03-15)
- 基于dsPIC33F系列单片机的应用程序升级方法(04-03)
- 采用混合时钟模式提高Linux时钟精度的方法(05-10)
- MSP430低功耗原理及其在海温测量中的应用(06-06)