以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 操作系统原理 』  (http://bbs.xml.org.cn/list.asp?boardid=63)
----  求助:编程模拟进程的同步与互斥  (http://bbs.xml.org.cn/dispbbs.asp?boardid=63&rootid=&id=54017)


--  作者:ww4052
--  发布时间:10/18/2007 11:52:00 AM

--  求助:编程模拟进程的同步与互斥
各位大侠:小弟最近学习操作系统。
求:编程模拟进程的同步与互斥!谢了!

--  作者:lukui
--  发布时间:11/17/2007 12:04:00 PM

--  
基于TURBO C环境下实现上述部分功能的算法,下面附以程序供参考
#include <stdlib.h>
#include <dos.h>
#include<stdio.h>

#include<math.h>
#define GET_INDOS 0x34
#define GET_CRIT_ERR 0x5d06
#define BLANK -1
#define FINISHED 0
#define RUNNING 1
#define READY 2
#define BLOCKED 3
#define NTCB 10
#define TL 3
#define NBUF 10
#define NTEXT 50
char far* indos_ptr=0;
char far* crit_err_ptr=0;
int timecount=0;
int current=-1;
char b[200];
   char words[200];

typedef struct
{
   int value;
   struct TCB* wq;
}semaphore;/*记录型信号量的结构*/

semaphore mutexfb={1,NULL};/*互斥信号量*/
semaphore sfb={10,NULL};/*空闲缓冲队列记数信号量*/

semaphore mutexre={0,NULL};
semaphore mutexse={0,NULL};

struct buffer{
   int sender;
   int size;
   char text[NTEXT];
   struct buffer* next;
}*freebuf;/*消息缓冲区数据结构*/

struct TCB
{
   unsigned char* stack;/*堆栈的起始地址*/
   unsigned ss;/*堆栈的段址*/
   unsigned sp;/*堆栈指针*/
   char state;/*进程状态*/
   char name[10];/*线程的外部标识符*/
   int value;
   struct TCB* next;
   struct buffer *mq;
   semaphore mutex;
   semaphore sm;
}tcb[NTCB];

struct int_regs
{
     unsigned Bp,DI,SI,DS,ES,DX,CX,BX,AX,IP,CS,Flags,off,seg;
};/*现场保护和恢复的数据结构*/


typedef int(far* codeptr)(void);

void interrupt (*old_int8)();/*原来的时间中断程序*/
int DosBusy(void);
void InitIndos(void);
void InitTcb();
void interrupt new_int8(void);/*具有按时间片调度功能的新的时钟中断函数*/
void interrupt swtch();/*因其它原因引起CPU调度*/
void send(char *receiver,char *a,int size);
void receive(char *sender,char *a);
void p(semaphore *sem);/*信号量P操作*/
void v(semaphore *sem);/*信号量V操作*/
int Create(char* name,codeptr code,int stacklen,int value);


void Destroy(int i);

/*void f1()
{
     int i,j;
     char msg[NTEXT];
     for(i = 1; i <= 50; i ++)
     {
         inttostr(msg, i * i);
         send("f2", msg, NTEXT);
         v(&mutexre);
         p(&mutexse);
         for(j = 0; j <= 1000; j ++);
     }
}*/

  

/*void f2()
{
     int i, j;
     char msg[NTEXT];
     for(i = 1; i <= 50; i ++)
     {
         p(&mutexre);
         receive("f1", msg);
         v(&mutexse);
         printf("%d * %d = %s\n", i, i, msg);
         for(j = 0; j <= 1000; j ++);
     }
}*/

/* InitInDos
This Funtion to get the address of INDOS and CRIT_ERR flags*/
void InitInDos()
{
   union REGS regs;
   struct SREGS segregs;
   /*get the address of INDOS flag*/
   regs.h.ah=GET_INDOS;
   intdosx(&regs,&regs,&segregs);


   indos_ptr=MK_FP(segregs.es,regs.x.bx);
   /*get the address of CRIT_ERR flag*/
   if(_osmajor<3)
     crit_err_ptr=indos_ptr+1;
   else if(_osmajor==3&&_osminor==0)
     crit_err_ptr=indos_ptr-1;
   else
     {
       regs.x.ax=GET_CRIT_ERR;
       intdosx(&regs,&regs,&segregs);
       crit_err_ptr=MK_FP(segregs.ds,regs.x.si);
     }
}
/* DosBusy Function return non_zero is busy*/
int DosBusy(void)
{
   if(indos_ptr&&crit_err_ptr)
     return (*indos_ptr||*crit_err_ptr);
   else
     return(-1);
}

void InitTcb()
{
   int i;
   for(i=0;i<NTCB;i++)
   {
     tcb[i].state=BLANK;
     tcb[i].mq=NULL;
     tcb[i].mutex.value=1;
     tcb[i].mutex.wq=NULL;
     tcb[i].sm.value=0;
     tcb[i].sm.wq=NULL;
   }
}

void over()
{
   Destroy(current);
   swtch();
}

int Create(char* name,codeptr code,int stacklen,int value)
{
   int i;
   char *p;
   struct int_regs* pt;
   for(i=1;i<NTCB;i++)
   {
     if(tcb[i].state==BLANK||tcb[i].state==FINISHED)
        break;
   }
   if(i==NTCB)
     return -1;
   tcb[i].value=value;
   strcpy(tcb[i].name,name);
   tcb[i].stack=p=(unsigned char*)malloc(stacklen);
   p=p+stacklen;
   pt=(struct int_regs *)p;
   pt--;
   pt->Flags=0x200;
   pt->CS=FP_SEG(code);
   pt->IP=FP_OFF(code);
   pt->off=FP_OFF(over);
   pt->seg=FP_SEG(over);
   pt->DS=_DS;
   pt->ES=_ES;
   tcb[i].sp=FP_OFF(pt);
   tcb[i].ss=FP_SEG(pt);
   tcb[i].state=READY;
   return i;
}

void Destroy(int i)
{
   if(tcb[i].state==RUNNING)
   {
     disable();
     tcb[i].state=FINISHED;
    
     free(tcb[i].stack);
     enable();
}
   return;
}

void tcb_state()
{
   int i;
   for(i=0;i<NTCB;i++)
      if(tcb[i].state!=BLANK)
      {
        switch(tcb[i].state)
        {
      case FINISHED:
        printf("tcb[%d] is FINISHED\n",i);
        break;
      case RUNNING:
        printf("tcb[%d] is RUNNING\n",i);
        break;
      case READY:
        printf("tcb[%d] is READY\n",i);
        break;
      case BLOCKED:
        printf("tcb[%d] is BLOCKED\n",i);
        break;
        }
      }
}

int Find()
{
   int i,j;
   for(i=0;i<NTCB;i++)
     if(tcb[i].state==READY&&i!=current)
       break;
     if(i==NTCB)
     return -1;
   for(j=i+1;j<NTCB;j++)
   {
      if(tcb[j].state==READY&&j!=current)
        if(tcb[j].value>tcb[i].value)
      i=j;
    }

   return i;
}
void Subvalue( void )
{
     tcb[current].value -=2;
}
void interrupt new_int8(void)
{
    int i;
    (*old_int8) ();
    timecount++;
    if(timecount==TL)
    {
      if(!DosBusy())
      {
     disable();
     tcb[current].ss=_SS;
     tcb[current].sp=_SP;
     Subvalue();
     if(tcb[current].state==RUNNING)
        tcb[current].state=READY;
     i=Find();
     if(i<0)
       i=0 ;
     _SS=tcb[i].ss;
     _SP=tcb[i].sp;
     tcb[i].state=RUNNING;
     current=i;
     timecount=0;
     enable();
      }
    
      
    }

   
}

void interrupt swtch()
{
   int i;
  
    
   i=Find();
   if(i<0)
      i=0 ;
   disable();
   tcb[current].ss=_SS;
   tcb[current].sp=_SP;
   if(tcb[current].state==RUNNING)
     tcb[current].state=READY;
   _SS=tcb[i].ss;
   _SP=tcb[i].sp;
   tcb[i].state=RUNNING;
   current=i;
   enable();
}
int all_finished()
{
   int i;
   for(i=1;i<NTCB;i++)
     if(tcb[i].state==RUNNING||tcb[i].state==BLOCKED||tcb[i].state==READY)
        return 0;
   return 1;
}


void block(struct TCB** p)
{
   struct TCB* p1;

   tcb[current].state=BLOCKED;

   if((*p)==NULL)
       *p=&tcb[current];
   else
   {
       p1=*p;
       while(p1->next!=NULL)
           p1=p1->next;
       p1->next=&tcb[current];
   }
   tcb[current].next=NULL;
   swtch();
}

void wakeup_first(struct TCB**p)
{
   struct TCB *p1;
   if((*p)==NULL)
       return ;
   p1=(*p);
   (*p)=(*p)->next;
   p1->state=READY;
   p1->next=NULL;
}


void p(semaphore *sem)
{
   struct TCB**qp;

   disable();
     sem->value=sem->value-1;
     if(sem->value<0)
      {
    
       qp=&(sem->wq);
       block(qp);
      }
   enable();
}

void v(semaphore *sem)
{
   struct TCB **qp;
   disable();
     qp=&(sem->wq);
     sem->value=sem->value+1;
     if(sem->value<=0)
       wakeup_first(qp);
   enable();
}

struct buffer *Initbuf(void)
{
   struct buffer *p,*pt,*pt2;
   int i;
   pt2=pt=(struct buffer*)malloc(sizeof(struct buffer));/*首节点*/
   pt->sender=-1;
   pt->size=0;
   strcpy(pt->text,"");
   pt->next=NULL;
   for(i=0;i<NBUF-1;i++)
   {
      p=(struct buffer*)malloc(sizeof(struct buffer));
      p->sender=-1;
      p->size=0;
      p->text[NTEXT]='\0';
      p->next=NULL;
      pt2->next=p;
      pt2=p;
   }
   return pt;
}

struct buffer *getbuf(void)
{
   struct buffer *buff;
   buff=freebuf;
   freebuf=freebuf->next;
   return(buff);
}

void putbuf(struct buffer* pt)
{
    struct buffer* p=freebuf;
    while(p->next!=NULL)
       p=p->next;
    p->next=pt;
    pt->next=NULL;
}

void insert(struct buffer** mq,struct buffer *buff)
{
   struct buffer *temp;

   if(buff==NULL) return ;
   buff->next=NULL;
   if(*mq==NULL)
     *mq=buff;
   else
   {
     temp=*mq;
     while(temp->next!=NULL)
       temp=temp->next;
     temp->next=buff;
   }
}

void send(char *receiver,char *a,int size)
{
   struct buffer *buff;
   int i,id=-1;

   disable();

   for(i=0;i<NTCB;i++)
   {
     if(strcmp(receiver,tcb[i].name)==0)
     {   id=i;
        break;
     }
   }
   if(id==-1)
   {
     printf("Error:Receiver not exist!\n");
     enable();
     return ;
   }

   p(&sfb);
   p(&mutexfb);
   buff=getbuf();
   v(&mutexfb);

   buff->sender=current;
   buff->size=size;
   buff->next=NULL;
   for(i=0;i<buff->size;i++,a++)
     buff->text[i]=*a;

   p(&tcb[id].mutex);
   insert(&(tcb[id].mq),buff);
   v(&tcb[id].mutex);
   v(&tcb[id].sm);


   enable();
}

void receive(char *sender,char *a)
{
   struct buffer *buff;
   int i;

   disable();
   for(i=0;i<NTCB;i++)
      if(strcmp(sender,tcb[i].name)==0)
     break;
   
   if(i==NTCB)
   {
       printf("Error:Sender not exist!\n");
       enable();
       return ;
   }

   p(&tcb[current].sm);
   p(&tcb[current].mutex);
   buff=tcb[current].mq;
   tcb[current].mq=tcb[current].mq->next;
   for(i=0;i<buff->size;i++,a++)
     b[i]=buff->text[i];
   b[i]='\0';
   a=b;
   v(&tcb[current].mutex);
   buff->sender=-1;
   buff->size=0;
   strcpy(buff->text,"");
   buff->next=NULL;
   p(&mutexfb);
   putbuf(buff);
   v(&mutexfb);
   v(&sfb);
  
   enable();
}
void sendfun(void)
{
     int i,j;
     int size;
     size=strlen(words);
     send("receiver",words,size);
     for(i=0;i<10000;i++)
         for(j=0;j<10000;j++);
      /*send("receiver","what are you doing",19);
      for(i=0;i<1000;i++)
         for(j=0;j<100;j++);   */

}
void sendfun1( char *receiver,char *a,int size )
{
     int i,j;
     send("receiver","hello",11);
     for(i=0;i<10000;i++)
         for(j=0;j<10000;j++);
      send("receiver","what are you ",19);
      for(i=0;i<1000;i++)
         for(j=0;j<100;j++);

}
/*void sendfun1( )
{
     int i,j;
     int size;
     size=st
     send("receiver",words,size);
     for(i=0;i<10000;i++)
         for(j=0;j<10000;j++);
      send("receiver","what are you ",19);
      for(i=0;i<1000;i++)
         for(j=0;j<100;j++);

}   */
void receivefun( void )
{
char *a;
int i,j;
             receive("sender",a)   ;
           printf("%50s\n",b);
             for(i=0;i<1000;i++)
         for(j=0;j<100;j++);

      /*    receive("sender",a)   ;
           printf("%s\n",b);

           receive("sender",a)   ;
           printf("%s\n",b);

                 receive("sender",a)   ;
          printf("%s\n",b);    */
}
void f1()
{
     int i,j,k,g;
     for(i=1;i<=50;i++)
     {
         printf("%d\n",i*i);
     for(j=0;j<1000;j++)
         for(k=0;k<1000;k++)
             for(g=0;g<100;g++);
     }
}
void f2()/*300以内的素数   */
{
     int i,j,k,g;
     int flag;
     for(i=2;i<=300;i++)
     {
         flag=0;
         for(j=2;j<sqrt(i*1.0)+1;j++)
             if(i%j==0)
             {
                 if(i!=2)
                 flag=1;
                 break;
             }
             if(!flag)
                 printf("%10d\n",i);
              for(g=0;g<10000;g++)
         for(k=0;k<1000;k++);
     }
}
void f3()
{
     long f1,f2,f;
     int i,j,g,k;
     f1=1,f2=0;
     for(i=1;i<=30;i++)
     {
         f=f1+f2;
         f1=f2;
         f2=f;
         printf("%25ld\n",f);
          for(j=0;j<100;j++)
         for(k=0;k<1000;k++)
             for(g=0;g<1000;g++);
     }
}
void InitView()
{int id;
     int value;
     disable();

    printf("thread 0# is main thread\n");
    printf("thread 1# is to calculate the number square from 1 to 50 \n");
    printf("thread 2# is to find prime number from 1 to 100\n");
    printf("thread 3# is to calculate the fib sequence number \n");
    printf("thread 4# is to send message\n");
    printf("thread 5# is to receive message\n");
   printf("select you want to create thread Id(0<id<6):(enter id<=0 is sover)\n");
while (scanf("%d",&id)&&id>0)
{       getchar();
      switch(id)
      {
        case 1:
            printf("Enter the %d# thread's value:",id);
            scanf("%d",&value);
            getchar();

            Create("f1",(codeptr)f1,1024,value);
            printf("%d# thread is create\n",id);
            break;
        case 2:
            printf("Enter the %d# thread's value:",id);
            scanf("%d",&value);
            getchar();

            Create("f2",(codeptr)f2,1024,value);
            printf("%d# thread is create\n",id);
            break;
        case 3:
            printf("Enter the %d# thread's value:",id);
            scanf("%d",&value);
            getchar();

            Create("f3",(codeptr)f3,1024,     value);
            printf("%d# thread is create\n",id);
            break;
        case 4:
            printf("Enter the %d# thread's value:",id);
            scanf("%d",&value);
            getchar();
            printf("Enter your message:");
              gets(words);
            Create("sender",(codeptr)sendfun,1024,value);
            printf("%d# thread is create\n",id);

            break;
        case 5:
            printf("Enter the %d# thread's value:",id);
            scanf("%d",&value);
            getchar();

            Create("receiver",(codeptr)receivefun,1024,value);
            printf("%d# thread is create\n",id);
            break;
      }
}
enable();
     
}


void main()
{
InitInDos();
InitTcb();
freebuf = Initbuf();

old_int8=getvect(8);                                               

strcpy(tcb[0].name,"main");
tcb[0].state=RUNNING;
tcb[0].value=0;

current=0;
  InitView();
Create("f1",(codeptr)f1,1024,5);
Create("f2",(codeptr)f2,1024,4);
Create("f3",(codeptr)f3,1024,2);

gets(words);
strcpy(words,"hollo\0");
Create("sender",(codeptr)sendfun,1024,6);

Create("receiver",(codeptr)receivefun,1024,7);

tcb_state();

setvect(8,new_int8);
swtch();
while(!all_finished());
tcb[0].name[0]='\0';
tcb[0].state=FINISHED;
setvect(8,old_int8);
printf("\n");
tcb_state();
printf("\n Muli_task system teminated \n");
getchar();
getchar();
getchar();
gets(words);

printf("\n Muli_task system teminated \n");
}


--  作者:ww4052
--  发布时间:11/18/2007 8:30:00 PM

--  
谢谢了!
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
109.131ms