操作系统:进程通信

    技术2022-05-11  10

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

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

    static int set_semvalue(void);static void del_semvalue(void);static int semaphore_p(void);static int semaphore_v(void);

    static int sem_id;

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

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

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

    static int set_semvalue(void){         union semun sem_union;

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

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

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

    static int semaphore_v(void){         struct sembuf sem_b;

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


    最新回复(0)