面向函数的unix环境编程练习.docx
- 文档编号:8164939
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:19
- 大小:19.57KB
面向函数的unix环境编程练习.docx
《面向函数的unix环境编程练习.docx》由会员分享,可在线阅读,更多相关《面向函数的unix环境编程练习.docx(19页珍藏版)》请在冰豆网上搜索。
面向函数的unix环境编程练习
面向函数的unix环境编程练习
函数练习
1.对mmap映射地址操作
mmap(),fstat()
mmap():
将文件和设备空间映射到内存中,内存操作比磁盘更快。
映射成功返回内存地址,是被返回-1.之后可以直接对映射的地址进行操作。
fstat()获取文件的状态。
#include
#include
#include
#include
#include
#include
#include
#include
intmain(){
intfd=open("doc1",O_RDONLY|O_CREAT,0755);
if(fd==-1){
perror("open");
exit
(1);
}
structstatinfo;
fstat(fd,&info);
/*startsetNULL,meanssystemsetit.*/
/*PROT_READmeansmemorycanberead.*/
/*MAP_PRIVATEmeanscreateacopyfile,notinfluceoriginfile.*/
void*start=mmap(NULL,info.st_size,PROT_READ,MAP_PRIVATE,fd,0);
if(start==MAP_FAILED){
perror("mmap");
exit
(1);
}
printf("%s",(char*)start);
munmap(start,info.st_size);
close(fd);
return0;
}
本程序将打印文件的内容。
如果文件的内容为空,那么将会出现,invalidargument的错误。
2.从标准输入到标准输出
read(),write()
#include
#include
#include
#include
#include
intmain(){
intn;
charbuf[1000];
while((n=read(STDIN_FILENO,buf,1000))>0){
//printf("output:
");
if(write(STDOUT_FILENO,buf,n)!
=n){
printf("writeerror\n");
}
}
if(n<0)printf("readerror\n");
return0;
}
/*
$./stdin_out
Isf
Isf
sd
sd
sdfsdf
sdfsdf
//output:
output:
output:
*/
read()函数是你输入什么,它读取什么的严格类函数。
(除了ctrl+D,ctrl+C等特殊情况)
3.查看标准输入的读写属性
fcntl()
使用fcnt()查看文件的属性。
#include
#include
#include
intmain(){
intflag=fcntl(STDIN_FILENO,F_GETFL,0);
if(flag<0){
perror("error:
");
return-1;
}
intresult=flag&O_ACCMODE;
if(result==O_RDONLY){
printf("stdinreadonly\n");
}
elseif(result==O_WRONLY){
puts("stdinwriteonly");
}
elseif(result==O_RDWR){
puts("stdinreadandwrite");
}
elseputs("stdinunknownmode");
if(flag&O_APPEND)puts("stdinappend");
if(flag&O_NONBLOCK)puts("stdinnonblock");
return0;
}
/*
./F_GETFL
stdinreadandwrite
*/
4.终端交互,创建进程
fork(),fgets(),execlp()
使用fork()克隆一个新的进程。
fork()有两个返回值,父进程中返回子进程的ID,子进程返回0。
forfgets():
出现换行字符、读到文件尾或是已读了size-1个字符才停止。
最后会加上NULL作为字符串结束,正常的返回值就是buf指针。
execlp():
从PATH环境变量中查找文件并执行
因为终端输入的命令实则是一个小程序,需要进程资源,所以在这里需要fork新的进程
#include
#include
#include
#include
#include
intmain(){
charbuf[100];
pid_tpid;
intstatus;
printf("%%");//output"%"
while(fgets(buf,100,stdin)!
=NULL){//getcmdfromstdin
intlen=strlen(buf);
if(buf[len-1]=='\n')buf[len-1]=0;
if((pid=fork())<0)puts("forkerror");//createnewprocess
elseif(pid==0){
execlp(buf,buf,NULL);//executebufcmdinnewprocess
printf("couldnotexecute%s",buf);
exit
(1);
}
if(pid=waitpid(pid,&status,0)<0)puts("waitpiderror");
printf("%%");
}
return0;
}
/*
execute:
%ls
4.12.shdex.shdoc3for.sht.ct
%date
SatAug2715:
55:
23CST2016
%who
rootpts/12016-08-2710:
10(10.21.1.109)
rootpts/02016-08-2709:
33(10.21.1.109)
%
*/
5.与文件的状态相关的写操作
fcntl()
在doc1文件中追加内容“Ilovelinux”
#include
#include
#include
#include
intmain(){
intfd=open("doc1",O_RDWR);
intflag=fcntl(fd,F_GETFL,0);
flag|=O_APPEND;
flag=fcntl(fd,F_SETFL,&flag);//文件的偏移量到了doc1的末尾
if(flag<0){
perror("fcntlerror:
");
return-1;
}
charbuff[]="Ilovelinux";
if(write(fd,buff,sizeof(buff))<0){
perror("writeerror:
");
}
close(fd);
return0;
}
6.读取文件的内容到字符串中
system(),fopen(),fgetc()
system()在使用/bin/bash如果失败则会返回127
看到fopen()可以直接使用字符串打开文件,瞬间喜欢上了它。
#include
#include
#include
#include
intmain(){
intcmd=system("pwd>pwd_r");
if(cmd==127||cmd==-1){
perror("systemerror:
");
return-1;
}
FILE*file=fopen("pwd_r","r");
if(file==NULL){
perror("openfileerror:
");
return-1;
}
charbuff[1005],ch;
inttop=0;
while((ch=fgetc(file))!
=EOF){
buff[top++]=ch;
}
buff[top]=0;
fclose(file);
printf("%s",buff);
return0;
}
/*
$./fopen_write
/home/wei/mycode/test
*/
7.使用管道,父进程给子进程写一条消息“helloworld.”
pipe(),fork(),read,write()
#include
#include
#include
#include
intmain(){
intfd[2];//0:
read1:
write
charbuff[50]="helloworld";
intresult=pipe(fd);
if(result==-1){
perror("createpipeerror:
");
return-1;
}
pid_tpid=fork();
if(pid==-1){
perror("forkerror:
");
return-1;
}
if(pid>0){//ifthisisoldprocess
result=write(fd[1],buff,strlen(buff));
printf("id:
%d\n",getpid());
return0;
}
else{//newprocess
read(fd[0],buff,sizeof(buff));
printf("id:
%dstring:
%s\n",getpid(),buff);
}
return0;
}
/*
$./pipe
id:
26517
id:
26518string:
helloworld
*/
8.阻塞的管道
fork()
观察下面的程序:
#include
#include
#include
intmain(){
charbuff[]="thismessageissentbychildprocess.";
intfd[2];
intresult=pipe(fd);
if(result<0){
perror("pipeerror:
");
return-1;
}
pid_tpid=fork();
if(pid<0){
perror("createprocesserror:
");
return-1;
}
elseif(pid==0){
close(fd[0]);
intlen=strlen(buff);
while(len>0){
intrd=write(fd[1],buff,len);
len-=rd;
if(rd<0){
perror("writeerror:
");
return-1;
}
else{
printf("haswrotedata:
%dleftdata:
%d\n",rd,len);
}
sleep(3);
if(len==0){
printf("writefinished.\n");
}
}
}
else{
close(fd[1]);
charreadbuff[105];
while
(1){
intget=read(fd[0],readbuff,105);
if(get<0){
perror("read:
");
return-1;
}
elseif(get==0){
printf("hereisnocontents.\n");
break;
}
else{
printf("data:
%s\n",readbuff);
}
}
}
return0;
}
/*
$./wait_pipe
haswrotedata:
38leftdata:
0#子进程写入数据
data:
thismessageissentbychildprocess.#父进程读入数据
writefinished.#回到了子进程
hereisnocontents.#这是父进程
//如果我们没有sleep(3)
haswrotedata:
38leftdata:
0#子进程
writefinished.#子进程
data:
thismessageissentbychildprocess.#父进程
hereisnocontents.#父进程
*/
9.消息队列sendandrecvmessage.
ftok(),msgget(),fgets()
key_tftok(constchar*fname,intid)
fname是指定的文件名(已经存在的文件名),一般使用当前目录,如:
key_tkey=ftok(“.”,1);id是子序号。
只使用8bits(1-255)。
用于保证两个不同用户下的两组相同程序获得互不干扰的IPC键值。
msgget()用于chungking或者打开消息队列。
//send.c:
#include
#include
#include
#include
#include
#include
#include
#defineMax105
typedefstructmsgmbuf{
intmsg_type;
charmsg_text[Max];
}MsgBuf;
intmain(){
printf("sendprocessstart:
%d\n",getpid());
printf("enteryourmessagetosend,and\"end\"willkillbothprocess.\n");
charbuff[Max];
MsgBufsendmsg;
char*msgpath="./me";//thepathofcreatemessage
key_tkey=ftok(msgpath,'a');
if(key==-1){
perror("createkeyerror:
");
return-1;
}
intmsgid=msgget(key,IPC_CREAT|0777);
if(msgid==-1){
perror("msggeterror:
");
return-1;
}
while
(1){
printf("pleaseentermsg:
");
fgets(buff,Max,stdin);//fileentercontents
sendmsg.msg_type=1;
strcpy(sg.msg_text,buff);
if(msgsnd(msgid,(void*)&sendmsg,Max,0)){
perror("msgsnderror:
");
return-1;
}
if(strcmp(buff,"end\n")==0){
printf("sendprocessend.\n");
return0;
}
}
return0;
}
//recv.c:
#include
#include
#include
#include
#include
#include
#include
#defineMax105
typedefstructmsgmbuf{
intmsg_type;
charmsg_text[Max];
}MsgBuf;
intmain(){
printf("recvprocessstart:
%d\n",getpid());
charbuff[Max];
char*msgpath="./me";
key_tkey=ftok(msgpath,'a');
intmsgid=msgget(key,IPC_CREAT|0777);
if(msgid==-1){
perror("msggeterror:
");
return-1;
}
MsgBufrecmsg;
while
(1){
if(msgrcv(msgid,(void*)&recmsg,Max,0,0)==-1){
perror("msgrcverror:
");
return-1;
}
if(strcmp(recmsg.msg_text,"end\n")==0){
printf("recvprocessend.\n");
break;
}
printf("recvmsg:
%s",recmsg.msg_text);
}
return0;
}
/*
$./send
sendprocessstart:
20436
enteryourmessagetosend,and"end"willkillbothprocess.
pleaseentermsg:
hehe
pleaseentermsg:
Iloveyou
pleaseentermsg:
end
sendprocessend.
./recv
recvprocessstart:
20437
recvmsg:
hehe
recvmsg:
Iloveyou
recvprocessend.
*/
10.不同进程利用共享内存通信
shmget(),shmctl()
//myshm.h
#include
#include
#include
#include
#include
#include
#defineSize105
//shm.c
#include"myshm.h"
intmain(){
key_tkey=ftok("./doc",'a');
intshmid=shmget(key,Size,IPC_CREAT|IPC_EXCL|0777);
if(shmid==-1){
puts("shmaredmemoryexit.hereisclient.");
if((shmid=shmget(key,Size,0))==-1){//thethirdnumberis0meanswecangettheexitmemoryid.
perror("shmgeterror:
");
return-1;
}
}
elseputs("creatednewsharedmemory");
charbuff[105],*content=NULL;
printf("Ifyouenter\"read\",wecangetcontents,or\"enter\",youcaninputnewthingsintosharedmemory.\
Otherwordswillkillprocess.\n");
while
(1){
printf("%%");
if(fgets(buff,Size,stdin)<0){
perror("fgetserror:
");
return-1;
}
content=(char*)shmat(shmid,0,0);
if(content==(char*)-1){
perror("shmat:
");
return-1;
}
if(strncmp(buff,"read",4)==0){
printf("data:
\n%s",content);
}
elseif(strncmp(buff,"enter",5)==0){
fgets(buff,Size,stdin);
strcat(content,buff);
printf("wroteit.");
}
else{
/*IPC_RMID命令实际上不从内核删除一个段,而是仅仅把这个段标记为删除,\
*实际的删除发生在最后一个进程离开这个共享段时。
*/
shmctl(shmid,IPC_RMID,0);
printf("theprocessend,By.\n");
break;
}
}
return0;
}
/*
./shm
creatednewsharedmemory
Ifyouenter"read",wecangetcontents,or"enter",youcaninputnewthingsintosharedmemory.Otherwordswillkillprocess.
%enter
Iloveyou
wroteit.%
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向 函数 unix 环境 编程 练习