⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux环境进程间通信(四).htm

📁 关于Linux内核进程间通信的几篇文章
💻 HTM
📖 第 1 页 / 共 4 页
字号:
{
	arg.val=1;
	if(semctl(semid,0,SETVAL,arg)==-1)
		perror("semctl setval error");
}
//get some information about the semaphore and the limit of semaphore in redhat8.0
	arg.buf=&sem_info;
	if(semctl(semid, 0, IPC_STAT, arg)==-1)
		perror("semctl IPC STAT");		
	printf("owner's uid is %d\n", 	arg.buf->sem_perm.uid);
	printf("owner's gid is %d\n", 	arg.buf->sem_perm.gid);
	printf("creater's uid is %d\n", 	arg.buf->sem_perm.cuid);
	printf("creater's gid is %d\n", 	arg.buf->sem_perm.cgid);
	arg.__buf=&sem_info2;
	if(semctl(semid,0,IPC_INFO,arg)==-1)
		perror("semctl IPC_INFO");
	printf("the number of entries in semaphore map is %d \n",	 		arg.__buf->semmap);
	printf("max number of semaphore identifiers is %d \n", 		 	arg.__buf->semmni);
	printf("mas number of semaphores in system is %d \n",		 		arg.__buf->semmns);
	printf("the number of undo structures system wide is %d \n",	 	arg.__buf->semmnu);
	printf("max number of semaphores per semid is %d \n",		 		arg.__buf->semmsl);
	printf("max number of ops per semop call is %d \n",		 		arg.__buf->semopm);
	printf("max number of undo entries per process is %d \n", 	 		arg.__buf->semume);
	printf("the sizeof of struct sem_undo is %d \n", 	  	 			arg.__buf->semusz);
	printf("the maximum semaphore value is %d \n", 					arg.__buf->semvmx);
	
//now ask for available resource:	
	askfor_res.sem_num=0;
	askfor_res.sem_op=-1;
	askfor_res.sem_flg=SEM_UNDO;		
		
		if(semop(semid,&askfor_res,1)==-1)//ask for resource
			perror("semop error");
	
	sleep(3); //do some handling on the sharing resource here, just sleep on it 3 seconds
	printf("now free the resource\n");	
	
//now free resource	
	free_res.sem_num=0;
	free_res.sem_op=1;
	free_res.sem_flg=SEM_UNDO;
	if(semop(semid,&free_res,1)==-1)//free the resource.
		if(errno==EIDRM)
			printf("the semaphore set was removed\n");
//you can comment out the codes below to compile a different version:			
	if(semctl(semid, 0, IPC_RMID)==-1)
		perror("semctl IPC_RMID");
	else printf("remove sem ok\n");
}
</PRE></TD></TR></TBODY></TABLE><BR>
            <P>注:读者可以尝试一下注释掉初始化步骤,进程在运行时会出现何种情况(进程在申请资源时会睡眠),同时可以像程序结尾给出的注释那样,把该程序编译成两个不同版本。下面是本程序的运行结果(操作系统redhat8.0):</P>
            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
              <TBODY>
              <TR>
                <TD class=code-outline><PRE class=displaycode>owner's uid is 0
owner's gid is 0
creater's uid is 0
creater's gid is 0
the number of entries in semaphore map is 32000 
max number of semaphore identifiers is 128 
mas number of semaphores in system is 32000 
the number of undo structures system wide is 32000 
max number of semaphores per semid is 250 
max number of ops per semop call is 32 
max number of undo entries per process is 32 
the sizeof of struct sem_undo is 20 
the maximum semaphore value is 32767 
now free the resource
remove sem ok
</PRE></TD></TR></TBODY></TABLE><BR>
            <P>Summary:信号灯与其它进程间通信方式有所不同,它主要用于进程间同步。通常所说的系统V信号灯实际上是一个信号灯的集合,可用于多种共享资源的进程间同步。每个信号灯都有一个值,可以用来表示当前该信号灯代表的共享资源可用(available)数量,如果一个进程要申请共享资源,那么就从信号灯值中减去要申请的数目,如果当前没有足够的可用资源,进程可以睡眠等待,也可以立即返回。当进程要申请多种共享资源时,linux可以保证操作的原子性,即要么申请到所有的共享资源,要么放弃所有资源,这样能够保证多个进程不会造成互锁。Linux对信号灯有各种各样的限制,程序中给出了输出结果。另外,如果读者想对信号灯作进一步的理解,建议阅读sem.h源代码,该文件不长,但给出了信号灯相关的重要数据结构。</P>
            <P>附录1: struct sem_array如下:</P>
            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
              <TBODY>
              <TR>
                <TD class=code-outline><PRE class=displaycode>/*系统中的每个信号灯集对应一个sem_array 结构 */
struct sem_array {
	struct kern_ipc_perm	sem_perm;		/* permissions .. see ipc.h */
	time_t			sem_otime;			/* last semop time */
	time_t			sem_ctime;			/* last change time */
	struct sem		*sem_base;			/* ptr to first semaphore in array */
	struct sem_queue	*sem_pending;		/* pending operations to be processed */
	struct sem_queue	**sem_pending_last; 	/* last pending operation */
	struct sem_undo		*undo;			/* undo requests on this array */
	unsigned long		sem_nsems;		/* no. of semaphores in array */
};
</PRE></TD></TR></TBODY></TABLE><BR>
            <P>其中,sem_queue结构如下:</P>
            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
              <TBODY>
              <TR>
                <TD class=code-outline><PRE class=displaycode>/* 系统中每个因为信号灯而睡眠的进程,都对应一个sem_queue结构*/
 struct sem_queue {
	struct sem_queue *	next;	 	/* next entry in the queue */
	struct sem_queue **	prev;	 	/* previous entry in the queue, *(q-&gt;prev) == q */
	struct task_struct*	sleeper; 	/* this process */
	struct sem_undo *	undo;	 	/* undo structure */
	int   pid;	 					/* process id of requesting process */
	int   status;	 				/* completion status of operation */
	struct sem_array *	sma;	 		/* semaphore array for operations */
	int	id;	 						/* internal sem id */
	struct sembuf *	sops;		 	/* array of pending operations */
	int	nsops;					 	/* number of operations */
	int	alter;	 					/* operation will alter semaphore */
};
</PRE></TD></TR></TBODY></TABLE><BR>
            <P>附录2:union semun是系统调用semctl中的重要参数:</P>
            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
              <TBODY>
              <TR>
                <TD class=code-outline><PRE class=displaycode>union semun {
	int val;					/* value for SETVAL */
	struct semid_ds *buf;		/* buffer for IPC_STAT &amp; IPC_SET */
	unsigned short *array;		/* array for GETALL &amp; SETALL */
	struct seminfo *__buf;		/* buffer for IPC_INFO */   //test!!
	void *__pad;
};
struct  seminfo {
	int semmap;
	int semmni;
	int semmns;
	int semmnu;
	int semmsl;
	int semopm;
	int semume;
	int semusz;
	int semvmx;
	int semaem;
};
</PRE></TD></TR></TBODY></TABLE><BR><BR><BR>
            <P><A name=resources><SPAN class=atitle>参考资料 </SPAN></A></P>
            <P>[1] UNIX网络编程第二卷:进程间通信,作者:W.Richard 
            Stevens,译者:杨继张,清华大学出版社。对POSIX以及系统V信号灯都有阐述,对Linux环境下的程序开发有极大的启发意义。</P>
            <P>[2] 
            linux内核源代码情景分析(上),毛德操、胡希明著,浙江大学出版社,给出了系统V信号灯相关的源代码分析,尤其在阐述保证操作原子性方面,以及阐述undo标志位时,讨论的很深刻。</P>
            <P>[3]GNU/Linux编程指南,第二版,Kurt Wall等著,张辉译</P>
            <P>[4]semget、semop、semctl手册</P><BR><BR>
            <P><A name=author><SPAN class=atitle>关于作者</SPAN></A></P>
            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
              <TBODY>
              <TR>
                <TD colSpan=3><IMG height=5 alt="" 
                  src="Linux环境进程间通信(四).files/c.gif" width="100%"></TD></TR>
              <TR vAlign=top align=left>
                <TD>
                  <P></P></TD>
                <TD><IMG height=5 alt="" src="Linux环境进程间通信(四).files/c.gif" 
                  width=4></TD>
                <TD width="100%">
                  <P>郑彦兴,男,现攻读国防科大计算机学院网络方向博士学位。您可以通过电子邮件 <A 
                  href="mailto:mlinux@163.com?cc=">mailto:mlinux@163.com?cc=</A>和他联系。 
                  </P></TD></TR></TBODY></TABLE><BR><BR><BR>
            <P class=no-print><SPAN class=atitle><A 
            name=rate>对本文的评价</A></SPAN></P><SPAN class=no-print>
            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
              <TBODY>
              <TR vAlign=top>
                <TD>
                  <FORM 
                  action=https://www.ibm.com/developerworks/secure/cnratings.jsp 
                  method=get><INPUT type=hidden value=Linux环境进程间通信(四) 
                  name=ArticleTitle><INPUT type=hidden value=Linux 
                  name=Zone><INPUT type=hidden 
                  value=http://www.ibm.com/developerworks/cn/thankyou/ 
                  name=RedirectURL><INPUT type=hidden value=china 
name=localsite>
                  <SCRIPT language=javascript>document.write('<input type="hidden" name="url" value="'+location.href+'" />');</SCRIPT>

                  <TABLE cellSpacing=0 cellPadding=0 border=0>
                    <TBODY>
                    <TR>
                      <TD><IMG height=8 alt="" 
                        src="Linux环境进程间通信(四).files/c.gif" width=100 
                    border=0></TD></TR>
                    <TR vAlign=top>
                      <TD><INPUT type=radio value=1 name=Rating>太差! (1)</TD></TR>
                    <TR vAlign=top>
                      <TD><INPUT type=radio value=2 name=Rating>需提高 (2)</TD></TR>
                    <TR vAlign=top>
                      <TD><INPUT type=radio value=3 name=Rating>一般;尚可 
(3)</TD></TR>
                    <TR vAlign=top>
                      <TD><INPUT type=radio value=4 name=Rating>好文章 (4)</TD></TR>
                    <TR vAlign=top>
                      <TD><INPUT type=radio value=5 
                    name=Rating>真棒!(5)</TD></TR></TBODY></TABLE><BR><B>建议?</B><BR><TEXTAREA id=Comments name=Comments rows=5 wrap=virtual cols=60>&nbsp;</TEXTAREA><BR><BR><INPUT type=submit value=反馈意见></FORM></TD></TR>
              <TR vAlign=top>
                <TD bgColor=#ffffff><IMG height=8 alt="" 
                  src="Linux环境进程间通信(四).files/c.gif" width=100 
              border=0></TD></TR></TBODY></TABLE></SPAN><SPAN class=no-print>
            <TABLE cellSpacing=0 cellPadding=0 align=right>
              <TBODY>
              <TR align=right>
                <TD><IMG height=8 alt="" src="Linux环境进程间通信(四).files/c.gif" 
                  width="100%"><BR>
                  <TABLE cellSpacing=0 cellPadding=0 border=0>
                    <TBODY>
                    <TR>
                      <TD vAlign=center><IMG height=16 alt="" 
                        src="Linux环境进程间通信(四).files/u_bold.gif" width=16 
                        border=0><BR></TD>
                      <TD vAlign=top align=right><A class=fbox 
                        href="http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/index.html#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR></SPAN></TD>
          <TD width=10><IMG height=1 alt="" src="Linux环境进程间通信(四).files/c.gif" 
            width=10></TD></TR></TBODY></TABLE><SPAN class=small>IBM 公司保留在 
      developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 <A 
      href="https://www.ibm.com/developerworks/secure/reprintreq.jsp?domain=dwchina">提交转载请求表单</A> 
      联系我们的编辑团队。</SPAN></TD></TR></TBODY></TABLE><!--FOOTER_BEGIN--><!-- IBM FOOTER -->
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
  <TBODY>
  <TR>
    <TD class=bbg height=19>
      <TABLE cellSpacing=0 cellPadding=0 border=0>
        <TBODY>
        <TR>
          <TD><SPAN class=spacer>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><A 
            class=mainlink href="http://www.ibm.com/cn/ibm/index.shtml">关于 
            IBM</A></TD>
          <TD class=footer-divider width=27>&nbsp;&nbsp;&nbsp;&nbsp;</TD>
          <TD><A class=mainlink 
            href="http://www.ibm.com/cn/ibm/privacy/index.shtml">隐私条约</A></TD>
          <TD class=footer-divider width=27>&nbsp;&nbsp;&nbsp;&nbsp;</TD>
          <TD><A class=mainlink href="http://www.ibm.com/contact/cn/">联系 
            IBM</A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><!-- end footer -->
<SCRIPT language=JavaScript1.2 src="Linux环境进程间通信(四).files/stats.js" 
type=text/javascript></SCRIPT>
<NOSCRIPT><IMG height=1 alt="" 
src="E:\sun_job\notebook\linux_进程间通信\Linux环境进程间通信(四).files\c(1).gif" width=1 
border=0></NOSCRIPT><!--FOOTER_END--><!--XSLT stylesheet used to transform this file:  dw-document-html-5.8.xsl--></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -