事务控制范例程序Word文档格式.docx
- 文档编号:19669313
- 上传时间:2023-01-08
- 格式:DOCX
- 页数:10
- 大小:17.92KB
事务控制范例程序Word文档格式.docx
《事务控制范例程序Word文档格式.docx》由会员分享,可在线阅读,更多相关《事务控制范例程序Word文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
intrc;
sigemptyset(&
sigs);
sigaddset(&
sigs,SIGTTOU);
sigprocmask(SIG_BLOCK,&
sigs,&
oldsigs);
rc=tcsetpgrp(ctty,pgrp);
sigprocmask(SIG_SETMASK,&
oldsigs,NULL);
returnrc;
}
/*类似fork函数,但做事务控制。
如果新建立的进程放在前台则设fg为真。
*(这样隐式地将调用方进程放置到后台,所以做完这个后要当心tty的输入/输出)
*设定pgrp为-1以创建一个新事务,在此情况下返回的进程号即是新事务的进程组号,
*或者设定一个同一会话中存在的事务(一般只用来启动管道操作的第二个或第二个以后
*的进程)。
pid_tspawn_job(intfg,pid_tpgrp)
intctty=-1;
pid_tpid;
/*如果生成一个*新*的前台事务,起码要求标准输入,标准输出或
*标准错误输出的其中一个指向的是控制tty,并且当前进程在前台。
*只有当在存在事务中开始一个新前台进程时才检查控制中的tty。
*一个没有控制tty的会话只能有后台事务。
if(fg)
pid_tcurpgrp;
if((curpgrp=tcgetpgrp(ctty=2))<
0
&
(curpgrp=tcgetpgrp(ctty=0))<
(curpgrp=tcgetpgrp(ctty=1))<
0)
returnerrno=ENOTTY,(pid_t)-1;
if(pgrp<
0&
curpgrp!
=getpgrp())
returnerrno=EPERM,(pid_t)-1;
switch(pid=fork())
case-1:
/*fork失败*/
returnpid;
case0:
/*子进程*/
/*建立新进程组,如果需要则将我们放到前台
*不知道如果setpgid函数调用失败该怎么办(“不会发生”)
pgrp=getpid();
if(setpgid(0,pgrp)==0&
fg)
assign_terminal(ctty,pgrp);
return0;
default:
/*父进程*/
/*这里也建立自进程组.*/
pgrp=pid;
setpgid(pid,pgrp);
/*不会执行到这里*/
/*用SIGNO表示的信号杀死PGRP表示的事务*/
intkill_job(pid_tpgrp,intsigno)
returnkill(-pgrp,signo);
/*中断PGRP表示的事务*/
intsuspend_job(pid_tpgrp)
returnkill_job(pgrp,SIGSTOP);
/*继续在后台执行PGRP表示的事务*/
intresume_job_bg(pid_tpgrp)
returnkill_job(pgrp,SIGCONT);
/*继续在前台执行PGRP表示的事务*/
intresume_job_fg(pid_tpgrp)
intctty;
if(curpgrp!
if(assign_terminal(ctty,pgrp)<
return-1;
/*将我们自己放置到前台,比如在中断一个前台事务之后调用
intforeground_self()
returnassign_terminal(ctty,getpgrp());
/*closeall()-关闭所有>
=给定FD的文件描述符*/
voidcloseall(intfd)
intfdlimit=sysconf(_SC_OPEN_MAX);
while(fd<
fdlimit)
close(fd++);
/*类似system()函数,但将给定的命令作为后台事务执行,返回shell进程
*的进程号(并且也是这个事务的进程组号,适用于kill_job等等)。
*如果参数INFD,OUTFD或ERRFD为非NULL,则打开一个管道和一个文件描述
*符保存与该管道有关的父进程端,然后在子进程中将被从定向到/dev/null。
*并且在子进程中关闭所有>
2的文件描述符(一个经常过份估计的工作)
pid_tspawn_background_command(constchar*cmd,
int*infd,int*outfd,int*errfd)
intnullfd=-1;
intpipefds[3][2];
interror=0;
if(!
cmd)
returnerrno=EINVAL,-1;
pipefds[0][0]=pipefds[0][1]=-1;
pipefds[1][0]=pipefds[1][1]=-1;
pipefds[2][0]=pipefds[2][1]=-1;
if(infd&
pipe(pipefds[0])<
error=errno;
elseif(outfd&
pipe(pipefds[1])<
elseif(errfd&
pipe(pipefds[2])<
error&
!
(infd&
outfd&
errfd))
nullfd=open("
/dev/null"
O_RDWR);
if(nullfd<
error)
pid_tpid=spawn_job(0,-1);
switch(pid)
break;
dup2(infd?
pipefds[0][0]:
nullfd,0);
dup2(outfd?
pipefds[1][1]:
nullfd,1);
dup2(errfd?
pipefds[2][1]:
nullfd,2);
closeall(3);
execl("
/bin/sh"
"
sh"
-c"
cmd,(char*)NULL);
_exit(127);
close(nullfd);
if(infd)
close(pipefds[0][0]),*infd=pipefds[0][1];
if(outfd)
close(pipefds[1][1]),*outfd=pipefds[1][0];
if(errfd)
close(pipefds[2][1]),*errfd=pipefds[2][0];
/*只在错误时执行到这里*/
inti,j;
for(i=0;
i<
3;
++i)
for(j=0;
j<
2;
++j)
if(pipefds[i][j]>
=0)
close(pipefds[i][j]);
if(nullfd>
returnerrno=error,(pid_t)-1;
/*---------------------------------------*/
/*这里是使用上述函数一个小例子.*/
pid_tbgjob=-1;
volatileintsigno=0;
#ifndefWCOREDUMP
/*如果没有WCOREDUMP,你也许会希望在你的平台上为它设置一个准确的定义
*(这通常是(status&
0x80)但也不总是这样),或者就赌没有coredumps(
*就象这个程序所做)
#defineWCOREDUMP(status)(0)
#endif
intcheck_children()
intstatus;
intcount=0;
while((pid=waitpid(-1,&
status,WNOHANG|WUNTRACED))>
if(pid==bgjob&
WIFSTOPPED(status))
bgjob=-1;
++count;
if(WIFEXITED(status))
fprintf(stderr,"
Process%ldexitedwithreturncode%d\n"
(long)pid,WEXITSTATUS(status));
elseif(WIFSIGNALED(status))
Process%ldkilledbysignal%d%s\n"
(long)pid,WTERMSIG(status),
WCOREDUMP(status)?
"
(coredumped)"
:
"
);
elseif(WIFSTOPPED(status))
Process%ldstoppedbysignal%d\n"
(long)pid,WSTOPSIG(status));
else
Unexpectedstatus-pid=%ld,status=0x%x\n"
(long)pid,status);
returncount;
voidsighandler(intsig)
if(sig!
=SIGCHLD)
signo=sig;
intmain()
structsigactionact;
intsigcount=0;
act.sa_handler=sighandler;
act.sa_flags=0;
act.sa_mask);
sigaction(SIGINT,&
act,NULL);
sigaction(SIGQUIT,&
sigaction(SIGTERM,&
sigaction(SIGTSTP,&
sigaction(SIGCHLD,&
Startingbackgroundjob'
sleep60'
\n"
bgjob=spawn_background_command("
sleep60"
NULL,NULL,NULL);
if(bgjob<
perror("
spawn_background_command"
exit
(1);
Backgroundjobstartedwithid%ld\n"
(long)bgjob);
while(bgjob>
if(signo)
Signal%dcaught\n"
signo);
if(sigcount++)
kill_job(bgjob,SIGKILL);
kill_job(bgjob,SIGTERM);
kill_job(bgjob,SIGCONT);
check_children())
pause();
Done-exiting\n"
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 事务 控制 范例 程序