首 页文章中心

Linux学习网

您的位置Linux学习网 > Linux综合 > 文章内容

操作系统:进程间通信

作者:佚名  来源:不详  发布时间:2007-12-21 16:41:00
class="diaryContent" id="diary4071914" style="DISPLAY: block">

#include<unistd.h>sSFLinux联盟
#include<stdlib.h>sSFLinux联盟
#include<stdio.h>sSFLinux联盟
#include<sys/types.h>sSFLinux联盟
#include<sys/ipc.h>sSFLinux联盟
#include<sys/sem.h>

#ifndef _SEMUN_H          //条件编译,即若SEMUN在头文件中没有被定义,就进行下面的编译sSFLinux联盟
#define _SEMUN_HsSFLinux联盟
union semun{     sSFLinux联盟
   int val;                          //设置semnum指定的信号量的值sSFLinux联盟
   struct semid_ds *buf;    sSFLinux联盟
   unsigned short int *array;sSFLinux联盟
   struct seminfo *_buf;sSFLinux联盟
};sSFLinux联盟
#endif

sSFLinux联盟
static int set_semvalue(void);sSFLinux联盟
static void del_semvalue(void);sSFLinux联盟
static int semaphore_p(void);sSFLinux联盟
static int semaphore_v(void);

static int sem_id;

int main(int argc,char *argv[]){sSFLinux联盟
   int i;sSFLinux联盟
   int pause_time;sSFLinux联盟
   char *op_in="First in\n";sSFLinux联盟
   char *op_out="First out\n";

   srand((unsigned int)getpid());                    //以getpid()为随机序列的种子sSFLinux联盟
   sem_id=semget((key_t)1234,1,0666|IPC_CREAT);   /*为一个新创建的集合返回标识符,sSFLinux联盟
                                             或者返回具有相同键值的已存在信号集的标识符*/

   if(argc>1){sSFLinux联盟
      if(!set_semvalue()){                         //信号初始化失败sSFLinux联盟
         fprintf(stderr,"Failed to initialize semaphore\n");sSFLinux联盟
      }sSFLinux联盟
      op_in="Second in\n";sSFLinux联盟
      op_out="Second out\n";sSFLinux联盟
      sleep(2);sSFLinux联盟
   }sSFLinux联盟
   for(i=0;i<5;i++){sSFLinux联盟
      if(!semaphore_p())sSFLinux联盟
         exit(EXIT_FAILURE);sSFLinux联盟
      printf("%s",op_in);sSFLinux联盟
      fflush(stdout);sSFLinux联盟
      pause_time=rand()%3;sSFLinux联盟
      sleep(pause_time);sSFLinux联盟
      printf("%s",op_out);sSFLinux联盟
      fflush(stdout);sSFLinux联盟
   sSFLinux联盟
      if(!semaphore_v())sSFLinux联盟
         exit(EXIT_FAILURE);sSFLinux联盟
      pause_time=rand()%2;sSFLinux联盟
      sleep(pause_time);sSFLinux联盟
   }sSFLinux联盟
   printf("\n%d-finished\n",getpid());sSFLinux联盟
   sSFLinux联盟
   if(argc>1){sSFLinux联盟
      sleep(10);sSFLinux联盟
      del_semvalue();sSFLinux联盟
   }sSFLinux联盟
   exit(EXIT_SUCCESS);sSFLinux联盟
}

sSFLinux联盟
static int set_semvalue(void){      sSFLinux联盟
   union semun sem_union;

   sem_union.val=1;sSFLinux联盟
   if(semctl(sem_id,0,SETVAL,sem_union)==-1)     /* 根据sem_union.val设置semmun指定的信号量的值,sSFLinux联盟
                                                错误返回-1,成功返回正数 */sSFLinux联盟
      return(1);                               //前面条件成立,即返回-1,则返回调用函数中的值为1sSFLinux联盟
}

static void del_semvalue(void){                sSFLinux联盟
   union semun sem_union;sSFLinux联盟
   if(semctl(sem_id,0,IPC_RMID,sem_union)==-1)   /* 从系统中删除标识符为sem_id的信号集,sSFLinux联盟
                                               错误返回-1,正确返回正数 */sSFLinux联盟
      fprintf(stderr,"Failed to delete semaphore\n");sSFLinux联盟
}

static int semaphore_p(void){sSFLinux联盟
   struct sembuf sem_b;        //sembuf结构在Linux/sem.h中有定义sSFLinux联盟
  sSFLinux联盟
   sem_b.sem_num=0;          //信号在数组中的索引sSFLinux联盟
   sem_b.sem_op=-1;          /* 这里为负数,相当于P操作,从信号量中减去sem_op的绝对值(1) */sSFLinux联盟
                               sSFLinux联盟
                               sSFLinux联盟
   sem_b.sem_flg=SEM_UNDO; /*操作标志为SEM_UNDO,当一个进程改变了信号量的值进入临界区后,sSFLinux联盟
                           但因为其他原因没有退出临界区的情况下,会造成信号量永远不能释放,sSFLinux联盟
                         此时,系统用SEM_UNDO实施还原操作,信号量还原为进程操作前的状态 */sSFLinux联盟
   if(semop(sem_id,&sem_b,1)==-1){     //P操作发生错误,返回-1,条件成立;否则条件不成立sSFLinux联盟
      fprintf(stderr,"semaphore_p failed");sSFLinux联盟
      return(0);               //上面的条件成立,即发生错误,返回0给调用函数sSFLinux联盟
   }sSFLinux联盟
}         //luojiazhen corrected it 05年12月20日

sSFLinux联盟
static int semaphore_v(void){      sSFLinux联盟
   struct sembuf sem_b;

   sem_b.sem_num=0;sSFLinux联盟
   sem_b.sem_op=1;            /* 这里为正数,相当于V操作,在信号量中增加sem_op的值(1),sSFLinux联盟
                                 这意味着该进程从临界区返回,释放临界资源 */         sSFLinux联盟
   sem_b.sem_flg=SEM_UNDO;sSFLinux联盟
      sSFLinux联盟
   if(semop(sem_id,&sem_b,1)==-1){      //V操作发生错误,返回-1,条件成立;否则条件不成立sSFLinux联盟
      fprintf(stderr,"semaphore_v failed");sSFLinux联盟
      return(0);sSFLinux联盟
   }sSFLinux联盟
   return(1);sSFLinux联盟
}

sSFLinux联盟
sSFLinux联盟

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=621907

收藏本页到: 365Key | del.icio.us | | 添加到雅虎收藏+
  • 网站帮助 - 广告合作 - 网站地图