【操作系統】Dos下的多任務系統

操作系統的課程設計作業之一,想想當初關於這段代碼被老師拷問成了狗,簡直是生命不能承受之重啊.如果有學弟選擇了周旭老師的操作系統,我唯一能幫助你的就是代碼拿過去用.還有他是個好老師.


代碼必須在Turbo C2.0環境下運行,因爲需要用到interupt關鍵字.

#include <dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/*
** #include "indos.c"
** #include "exterr.c"
*/

#define GET_INDOS 0X34           /*未公開的34h號系統功能調用,可得到INDOS標誌的地址(由ES:BX返回)*/
#define GET_GRIT_ERR 0X5D06

#define NTCB 5                   /*系統允許的最多任務數*/
#define NTEXT 20                 /*消息字符串的最大長度*/
#define NBUF  5                  /*緩衝隊列的最大長度*/

/* state code */
/* null		0		not assigned */

#define FINISHED        0       /*線程的狀態標誌 */
#define	RUNNING	        1       /*線程的狀態標誌 */
#define READY 	        2       /*線程的狀態標誌 */
#define BLOCKED         3       /*線程的狀態標誌 */

#define NAME_MAX        10      /*線程外部標識符的最大長度*/

/*
unsigned oldss;
unsigned oldsp;
*/

static int current = 0;	/* 當前正在執行程序的內部標誌符 */
int multstop = 1;       /*  */
int timecount = 0;      /*記錄當前線程從上次調度至今已經運行了多少時鐘中斷間隔 單位 1/18.2second*/
int TL;                 /*時間片的大小*/
int n = 0;
int buf1;

char far *indos_ptr = 0 ;           /*存放INDOS標誌的地址*/
char far *crit_err_ptr = 0 ;        /*存放嚴重錯誤標誌的地址*/

/* the pointer to the process's code  */
typedef int (far *codeptr)(void);


typedef struct
{
        int value;
        struct TCB *wq;      /*  */
} semaphore;

semaphore mutexfb = {1, NULL};            /* 消息緩衝隊列的互斥信號量 */
semaphore sfb = {NBUF, NULL};             /* 消息緩衝隊列的計數信號量 */
semaphore mutex = {1, NULL};              /* 接收隊列的消息隊列的互斥信號量 */
semaphore sa = {1, NULL};                 /* */
semaphore sb = {0, NULL};

struct buffer
{
        int id;
        int size;
        char text[NTEXT];
        struct buffer *next;
} buf[NBUF], *freebuf;             /*freebuf:空閒緩衝隊列(是一臨界資源)*/

struct TCB
{
        int priority;           /* 線程的優先級 0~10 */
        int id;                 /* 每個線程的唯一的內部標識符 */
        unsigned sp;
        unsigned ss;
        unsigned int *chan;             /* event process is awaiting */
        struct buffer *mq;
        semaphore mutex;
        semaphore sm;                   /* 接受線程的消息隊列的計數信號量,用於實現同步 */
        struct TCB *next;               /* link pointer */
        char name[NAME_MAX];	        /* 每個進程的外部標識符 */
        unsigned char *stack;           /* 堆棧的起始地址 */
        char state;                     /* 線程的狀態 */
} tcb[NTCB] ;


/* the registers pushed in the stack after entering an interrupt funtion */


struct int_regs
{
        unsigned bp;
        unsigned di;
        unsigned si;
        unsigned ds;
        unsigned es;
        unsigned dx;
        unsigned cx;
        unsigned bx;
        unsigned ax;
        unsigned ip;
        unsigned cs;

        unsigned flags;

        unsigned off;
        unsigned seg;
};


void interrupt (*old_int8)(void);           /*函數指針*/

void interrupt new_int8(void);              /*函數:解決因時間片到時引起的調度*/

int create(char *name, codeptr code, int stck, int priority_num);/*創建一個線程,讓其執行code開始的代碼*/

void destroy(int id);            /*撤銷一個線程*/

void over(void);
/*如果是當前線程運行完成而引起現場給你撤銷,則系統能自動撤銷該線程,並重新進行CPU調度,先調用destroy()*/

void interrupt swtch(void);     /*調度程序函數:(原因)1.線程執行完畢 2.阻塞*/

int all_finished(void);         /*檢查系統中除了0#線程以外的所有其他線程是否都已經運行完成,是返回1,否返回0*/

void free_all(void);            /*把TCB數組全部釋放掉*/

void tcb_state(void);           /*輸出所有的線程的當前狀態信息*/

void InitTcb(void);             /*創建空白的TCB數組並初始化*/

int DosBusy(void);              /*判斷是否DOS忙*/

void block(unsigned *chan, struct TCB **qp);

void free_all(void);

struct buffer *getbuf(void);       /* 獲取空閒緩衝區函數 */

void init_buf(void);

void InitInDos(void);

void insert(struct buffer **mq, struct buffer *buff);     /* 插入緩衝區到緩衝隊列函數 */

void interrupt new_int8(void);      /* 調度程序的函數:解決因時間片到時引起的調度(通過截斷時鐘中斷int08)*/

void over(void);

void p(semaphore *sem);

void p(semaphore *sem);

int receive(char *sender,char *b);      /* 接受原語 */

void receiver(void);

struct buffer *remov(struct buffer **mq, int sender);   /* 獲取消息緩衝區隊列函數 */

void sender(void);

void interrupt swtch(void);

void wakeup_first(struct TCB **qp);

void f1(void);

void f2(void);

void f3(void);

void f4(void);

void f5(void);

void f6(void);

void cp(void);

void cp1(void);

void iop(void);

void iop1(void);

int main(void)
{
        int temp;       //這個變量用來存儲create函數的返回值,從而判斷create是否成功

	int sele = -1;             //selection:選擇對應操作的序號
	char name[NAME_MAX];

	InitInDos();               /*獲得INDOS標誌的地址和嚴重錯誤標誌的地址*/
	InitTcb();
	old_int8 = getvect(8);     /*獲取系統原來的INT08H的中斷服務程序的入口地址*/

	/* 創建 #0# 號進程 */
	strcpy(tcb[0].name, "main");
	tcb[0].state = RUNNING;
	current = 0;

	for(; sele;)
	{
		do
		{
			clrscr();
			printf("\n\n\n\t***********************************************************\n");
			printf("\t* 0.退出多任務系統:                               *\n");
			printf("\t* 1.線程的\"順序\"執行:                      *\n");
			printf("\t* 2.線程的併發執行:                    *\n");
			printf("\t* 3.線程同時共享臨界資源: *\n");
			printf("\t* 4.線程互斥共享臨界資源: *\n");
			printf("\t* 5.線程沒做好同步時情況:                  *\n");
			printf("\t* 6.線程同步時的情況:                       *\n");
			printf("\t* 7.線程間的通信:                          *\n");
			printf("\t***********************************************************\n\n");
			printf("\t 請輸入對應的數字(0-7):");
			scanf("%d", &sele);
		}
		while(sele<0 || sele>7) ;

		switch(sele)
		{
		case 1:
			temp = create("f1", (codeptr)f1, 1024, 5);
			if(temp == -1)
                        {
                                printf("創建線程失敗!\n");
                                exit(EXIT_FAILURE);
                        }
			temp = create("f2", (codeptr)f2, 1024, 6);
			if(temp == -1)
                        {
                                printf("創建線程失敗!\n");
                                exit(EXIT_FAILURE);
                        }
			clrscr();
			printf("\t 不剝奪方式下兩個線程的併發執行 \n");
			printf("\t 其中線程f1不斷輸出字母a,共1000次 ;\n");
			printf("\t 而線程f2不斷輸出字母b,共100次 ;\n");
			printf("\t 按任意鍵繼續!\n");
			getch();
			swtch();/*輸出*/
			break;

		case 2:
			temp = create("f1", (codeptr)f1, 1024, 5);
			if(temp == -1)
                        {
                                printf("創建線程失敗!\n");
                                exit(EXIT_FAILURE);
                        }
			temp = create("f2", (codeptr)f2, 1024, 6);
			if(temp == -1)
                        {
                                printf("創建線程失敗!\n");
                                exit(EXIT_FAILURE);
                        }

			clrscr();
			printf("\t 時間片輪轉方式下兩個線程的併發執行\n");/**/
			printf("\t 其中線程f1不斷輸出字母a,共1000次;\n");/**/
			printf("\t 而線程f2不斷輸出字母b,共100次。\n");/**/
			printf("\t 請設置時間片的大小(單位爲1/18.2秒):");/**/
			scanf("%d", &TL);
			printf("\t 按任意鍵繼續!\n");
			getch();
			setvect(8, new_int8);
			swtch();
			break;

		case 3:
			n = 0;
			temp = create("f3", (codeptr)f3, 1024, 5);
			if(temp == -1)
                        {
                                printf("創建線程失敗!\n");
                                exit(EXIT_FAILURE);
                        }
			temp = create("f4", (codeptr)f4, 1024, 6);
			if(temp == -1)
                        {
                                printf("創建線程失敗!\n");
                                exit(EXIT_FAILURE);
                        }

			clrscr();
			printf("\t 線索同時共享臨界資源的情況\n");/* */
			printf("\t 線程f3和f4共享一變量n;\n");/**/
			printf("\t times線程f3不斷對n進行加1操作,共進行100次;\n"); /**/
			printf("\t 線程f4也不斷對n進行加1操作,共進行100次;\n");/**/
			printf("\t 因此,最後n的值應爲200\n");/**/
			printf("\t 按任意鍵繼續!\n");
			getch();
			TL = 1;
			setvect(8, new_int8);
			swtch();
			break;

		case 4:
			n = 0;
			temp = create("f3", (codeptr)f5, 1024, 5);
			if(temp == -1)
                        {
                                printf("創建線程失敗!\n");
                                exit(EXIT_FAILURE);
                        }
			temp = create("f4", (codeptr)f6, 1024, 6);
			if(temp == -1)
                        {
                                printf("創建線程失敗!\n");
                                exit(EXIT_FAILURE);
                        }

			clrscr();
			printf("\t 線程互斥共享臨界資源: \n");
			printf("\t 線程f3和f4共享一變量n;\n");
			printf("\t 線程f3不斷對n進行加1操作,共進行100次\n");
			printf("\t 線程f4也不斷對n進行加1操作,共進行100次\n");
			printf("\t 因此,最後n的值應爲200\n");
			TL=1;
			printf("\t 按任意鍵繼續!\n");
			getch();
			setvect(8,new_int8);
			swtch();
			break;

		case 5:
			n = 0;
			create("iop", (codeptr)iop1, 1024, 5);
			create("cp", (codeptr)cp1, 1024, 6);
			clrscr();
			printf("\t 沒同步的計算進程和輸出進程的併發執行 \n");
			printf("\t 並將其放入一緩衝區\n");
			printf("\t 打印進程iop依次取出cp放入緩衝區中的數,將它輸出出來\n");
			printf("\t 本例中,cp計算出十個數,分別爲0,1,2,3,4,5,6,7,8,9\n");
			printf("\t 按任意鍵繼續!\n");
			getch();
			TL = 1;
			setvect(8, new_int8);
			swtch();
			break;

		case 6:
			n = 0;
			create("iop", (codeptr)iop, 1024, 5);
			create("cp", (codeptr)cp, 1024, 6);
			clrscr();
			printf("\t 經過同步的計算進程和輸出進程的併發執行:\n");
			printf("\t 計算進程cp不斷計算數,並將其放入一緩衝區,\n\n");
			printf("\t 打印進程iop依次取出cp放入緩衝區中的數,將它輸出出來.\n");
			printf("\t 本例中,cp計算出十個數,分別爲0,1,2,3,4,5,6,7,8,9\n");
			printf("\t 按任意鍵繼續!\n");
			getch();
			TL = 1;
			setvect(8,new_int8);
			swtch();
			break;

		case 7:
			init_buf();
			n = 0;
			create("sender", (codeptr)sender, 1024, 5);
			create("receiver", (codeptr)receiver, 1024, 6);
			printf("\t 線程間的通信:\n");
			printf("\t 線程sender調用send原語向線程receiver發送十個消息\n");
			printf("\t 十個消息的內容分別爲message0......message9\n");
			printf("\t 線程receiver調用receive接收sender發來的消息\n");
			printf("\t 本例中,消息緩衝的個數爲5個\n");
			printf("\t 按任意鍵繼續!\n");
			getch();
			TL = 1;
			setvect(8, new_int8);
			swtch();
			break;

		default:
			sele = 0;
            }

            while(!all_finished())
            {
                    NULL;
            }

            if(sele == 3)
            {
		    printf("因對臨界資源的共享沒互斥,本次運行的結果爲\n");
		    printf("n==%d\n", n);
            }
            if(sele == 4)
	    {

	    	    printf("n==%d\n",n);
	    }
            if(sele != 0)
            {
		    printf("除0號線程外,其餘線程都已執行完畢,請按任意鍵結束!\n");
		    getch();
            }

            setvect(8, old_int8);
        }

        printf("\t\t多任務系統結束運行\n");

        return 0;
}


int DosBusy(void)                   /*判斷是否DOS忙*/
{
        if(indos_ptr && crit_err_ptr)
        {
                return   (*indos_ptr || *crit_err_ptr);
        }
        else
        {
                return(-1);
        }
}                  /*用於判斷當前DOS是否處於繁忙狀態*/

void InitInDos()
{
        union   REGS   regs;
        struct   SREGS   segregs;
        regs.h.ah = GET_INDOS;         /*使用34H號系統功能調用*/
        intdosx(&regs, &regs, &segregs);
        indos_ptr = MK_FP(segregs.es, regs.x.bx);
        if(_osmajor < 3)
        {
                crit_err_ptr = indos_ptr + 1;       /*嚴重錯誤在INDOS後一字節處*/
        }
        else
        {
                if(_osmajor==3 && _osmajor==0)
                {
                        crit_err_ptr = indos_ptr - 1;       /*嚴重錯誤在INDOS前一字節處*/
                }
                else
                {
                        regs.x.ax = GET_GRIT_ERR;
                        intdosx(&regs, &regs, &segregs);
                        crit_err_ptr = MK_FP(segregs.ds, regs.x.si);
                }
        }

}                       /*初始化DOS,取得INDOS標誌和嚴重錯誤標誌地址*/

void InitTcb(void)
{
        int i;

        for(i=0; i<NTCB; i++)
        {
                tcb[i].priority = -1;
                tcb[i].stack = NULL;
                tcb[i].state = FINISHED;
                tcb[i].chan = NULL;
                tcb[i].name[0] = '\0';
                tcb[i].next = NULL;
                tcb[i].mq = NULL;
                tcb[i].mutex.value = 1;
                tcb[i].mutex.wq = NULL;
                tcb[i].sm.value = 0;
                tcb[i].sm.wq = NULL;
        }
}


int create(char *name,codeptr code,int stck, int priority_num)
{
        struct int_regs far *r;        /*指針*/
        int i;
        int id = -1;
        unsigned char *ptr;

        for(i=0; i<NTCB; i++)
        {
                if(tcb[i].state == FINISHED)
                {
                        id = i;
                        break;
                }
        }
        if(id == -1)
        {
                return id;  /*若創建失敗,則返回-1*/
        }

        disable();

        tcb[id].stack = (unsigned char *)malloc(stck);
        memset(tcb[id].stack, 0, stck);
        r = (struct int_regs *)(tcb[i].stack + stck - 1);
        r--;
        tcb[id].ss = FP_SEG(r);
        tcb[id].sp = FP_OFF(r);
        r->cs = FP_SEG(code);
        r->ip = FP_OFF(code);
        r->ds = _DS;      /*DS和ES爲CPU的寄存器*/
        r->es = _DS;
        r->flags = 0x200;         //512  ??????????
        r->seg = FP_SEG(over);      /*over is a function pointer  ,FP_SEG(p), 得到該地址的段地址*/
        r->off = FP_OFF(over);      /*over is a function pointer  ,FP_OFF(p), 得到該地址的段內偏移,MK_FP(seg,off)得到對應的指針*/
        tcb[id].state = READY;

        for(i=0; i<NAME_MAX; i++,name++)
        {
                if((tcb[id].name[i] = *name) == NULL)
                {
                        break;
                }
        }
        tcb[id].priority = priority_num;
        tcb[id].name[NAME_MAX - 1] = '\0';

        enable();

        return(id);
}

void destroy(int id)
{
        disable();

        free(tcb[id].stack);
        tcb[id].stack = NULL;           /*把指針指向NULL,防止野指針的生成*/
        tcb[id].state = FINISHED;
        printf("\n **** Thread %s is terminated ****\n", tcb[id].name);
        tcb[id].name[0] = '\0';

        enable();

}

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

void block(unsigned *chan, struct TCB **qp)
{
        int id;
        struct TCB *tcbp;

        id = current;
        tcb[id].state = BLOCKED;
        tcb[id].chan = chan;

        if((*qp) == NULL)
        {
                (*qp) = &tcb[id];
        }
        else
        {
		tcbp = *qp;

		while(tcbp->next != NULL)
		{
			tcbp = tcbp->next;
		}

		tcbp->next = &tcb[id];
        }

	tcb[id].next = NULL;

	swtch();
}

void wakeup_first(struct TCB **qp)
{
        int i;
        struct TCB *tcbp;

        if((*qp) == NULL)
        {
                return;
        }
        tcbp = (*qp);
        (*qp) = (*qp)->next;
        tcbp->state = READY;
        tcbp->chan = NULL;
        tcbp->next = NULL;
}

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

        disable();

        sem->value = sem->value - 1;
        if(sem->value < 0)
        {
                qp = &(sem->wq);           // **ask**
                block((unsigned *)sem, 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();
}


/*  該函數主要解決兩種原因引起的調度:
**  1.線程執行完畢
**  2.正在執行的線程因等待某事件發生而不能繼續執行
*/
void interrupt swtch(void)
{
        int loop = 0;

        disable();

	/* save the old process */
        tcb[current].ss = _SS;
        tcb[current].sp = _SP;
        if(tcb[current].state == RUNNING)
        {
		tcb[current].state = READY;
        }

	/* find a new process and restore it */
	if(++current == NTCB)
	{
                current = 0;

	}
	while(tcb[current].state!=READY && loop++<NTCB-1)
	{
		current++;
		if(current == NTCB)
		{
                        current = 0;
		}
	}
	if(tcb[current].state != READY)
        {
                current = 0;
        }


	_SS = tcb[current].ss;
	_SP = tcb[current].sp;
	tcb[current].state = RUNNING;
	timecount = 0;
	/* tcb_state();*/

	enable();
}

int all_finished(void)
{
	int i;

	for(i=1; i<NTCB; i++)
        {
		if(tcb[i].state != FINISHED)
                {
                        return(0);
                }

		return(1);
        }
}

void free_all(void)
{
	int i;

	for(i=0; i<NTCB; i++)
	{
		if(tcb[i].stack)
		{
			tcb[i].name[0] = '\0';
			tcb[i].state = FINISHED;

			free(tcb[i].stack);
			tcb[i].stack = NULL;          /*防止野指針的產生*/
		}
	}
}

void interrupt new_int8(void)      /*調度程序的函數:解決因時間片到時引起的調度(通過截斷時鐘中斷int08)*/
{
	int loop = 0;

	(*old_int8)();
	if(++timecount < TL)
        {
                return;
        }

	if(DosBusy())
        {
                return;
        }

	disable();

	tcb[current].ss = _SS;
	tcb[current].sp = _SP;

	if(tcb[current].state == RUNNING)
        {
		tcb[current].state = READY;
        }

	/* find a new process and restore it */
	if(++current == NTCB)
        {
                current = 1;
        }

	while(tcb[current].state!=READY && ++loop<NTCB-1)
	{
		current++;
		if(current == NTCB)
                {
                        current=1;
                }
	}
	if(tcb[current].state != READY)
        {
                current=0;
        }

	_SS = tcb[current].ss;
	_SP = tcb[current].sp;
	tcb[current].state = RUNNING;
	timecount = 0;
	/*    tcb_state();*/

	enable();
}

void tcb_state(void)
{
	int i;
	/*
	if(!multstop) return;
	*/

	printf("\n");
	for(i=0; i<NTCB; i++)
	{
		printf("proc %d(%9s):  ",i, tcb[i].name);
		switch(tcb[i].state)
		{
		case READY:
			printf("READY\n");
			break;

		case RUNNING:
			printf("RUNNING\n");
			break;

		case FINISHED:
			printf("FINISHED\n");
			break;

		case BLOCKED:
			printf("BLOCKED\n");
			break;

		}
	}
}

void init_buf(void)
{
	int i;
	for(i=0; i<NBUF-1; i++)
        {
		buf[i].next = &buf[i+1];
        }
	buf[i].next = NULL;
	freebuf = &buf[0];
}

struct buffer *getbuf(void)       /* 獲取空閒緩衝區函數 */
{
	struct buffer *buff;
	buff = freebuf;
	freebuf = freebuf->next;

	return(buff);
}

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;
	}
}

struct buffer *remov(struct buffer **mq, int sender)   /* 獲取消息緩衝區隊列函數 */
{
	struct buffer *p;
	struct buffer *q;
	struct buffer *buff;
	q = NULL;
	p = *mq;
	while((p->id != sender) && (p->next != NULL))
	{
		q = p;
		p = p->next;
	}
	if(p->id == sender)
	{
		buff = p;

		if(q == NULL)
                {
                        *mq = buff->next;
                }
		else
		{
                        q->next = buff->next;
		}

		buff->next = NULL;

		return(buff);
	}
	else
	{
		return(NULL);
	}
}

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

	disable();

	for(i=0; i<NTCB; i++)
	{
		if(strcmp(receiver,tcb[i].name) == 0)
		{
			id = i;
			break;
		}
	}
	if(id == -1)
	{
		enable();
		return;
	}

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

	buff->id = 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();
}

int receive(char *sender,char *b)      /* 接受原語 */
{
	int i;
	int size;
	int id = -1;
	struct buffer *buff;

	disable();

	for(i=0; i<NTCB; i++)
	{
		if(strcmp(sender,tcb[i].name) == 0)
		{
			id = i;
			break;
		}
	}
	if(id == -1)
	{
		enable();
		return(0);
	}

	p(&tcb[current].sm);
	p(&tcb[current].mutex);
	buff = remov(&(tcb[current].mq), id);
	v(&tcb[current].mutex);
	if(buff == NULL)
	{
		v(&tcb[current].sm);
		enable();
		return(-1);
	}
	size = buff->size;
	for(i=0; i<buff->size; i++, b++)
	{
                *b = buff->text[i];
	}
	p(&mutexfb);
	insert(&freebuf, buff);
	v(&mutexfb);
	v(&sfb);

	enable();
	return(size);
}




/*codeptr lookup(char *name){
int i;

  for(i=0;i<NTCB;i++){
  strcmp(name,table[i].name)==0)
  return(table[i].code);
  }
  return(NULL);
  }
*/

void f1(void)
{
	long i;
	long j;
	long k;

	for(i=0; i<1000; i++)
	{
		putchar('a');
		for(j=0; j<1000; j++)
		{
			for(k=0; k<100; k++)
                        {
                                NULL;
                        }
		}
	}
}

void f2(void)
{
	long i;
	long j;
	long k;
	for(i=0; i<100; i++)
	{
		putchar('b');
		for(j=0; j<1000; j++)
		{

			for(k=0; k<100; k++)
                        {
                                NULL;
                        }
                }
	}
}

/*int n=0;*/


void f3(void)
{
	long i;
	long j;
	long k;
	int temp;
	for(i=0; i<100; i++)
	{
		temp = n;
		delay(5);
		temp++;
		n = temp;
		for(j=0; j<1000; j++)
		{

			for(k=0; k<99; k++)
                        {
                                NULL;
                        }
		}
	}
}

void f4(void)
{
	long i;
	long j;
	long k;
	int temp;

	for(i=0; i<100; i++)
	{
		temp = n;
		temp++;
		delay(10);
		n = temp;
		for(j=0; j<1000; j++)
		{

			for(k=0; k<100; k++)
                        {
                                NULL;
                        }
		}
	}
}

/*semaphore mutex={1,NULL};*/

void f5(void)
{
	long i;
	long j;
	long k;
	int temp;
	for(i=0; i<100; i++)
	{
		p(&mutex);
		temp = n;
		delay(5);
		temp++;
		n = temp;
		v(&mutex);
		for(j=0; j<1000; j++)
		{

			for(k=0; k<99; k++)
                        {
                                NULL;
                        }
		}
	}
}

void f6(void)
{
	long i;
	long j;
	long k;
	int temp;

	for(i=0; i<100; i++)
	{
		p(&mutex);
		temp = n;
		temp++;
		delay(10);
		n = temp;
		v(&mutex);
		for(j=0; j<1000; j++)
		{

			for(k=0; k<100; k++)
                        {
                                NULL;
                        }
		}
	}
}

/* int buf1;
** semaphore sa={1,NULL},sb={0,NULL};
*/

void cp1(void)
{
	int i;
	for(i=0; i<10; i++)
	{
		n++;
		buf1 = n;
	}
}

void iop1(void)
{
	int i;
	int tem;
	for(i=0; i<10; i++)
	{
		tem = buf1;
		printf("Out %d:%d\n", i, tem);
	}
}

void cp(void)
{
	int i;
	for(i=0; i<10; i++)
	{
		n++;
		p(&sa);
		buf1 = n;
		v(&sb);
	}
}

void iop(void)
{
	int i;
	int tem;
	for(i=0; i<10; i++)
	{
		p(&sb);
		tem = buf1;
		v(&sa);
		printf("Out %d:%d\n", i, tem);
	}
}

void sender(void)           /* 發送線程的外部標識符 */
{
	int i;
	int j;
	char a[10];
loop:
	for(i=0; i<10; i++)
	{
		strcpy(a, "message");
		a[7] = '0' + n;
		a[8] = 0;
		send("receiver", a, strlen(a));
		printf("sender:Message \"%s\"  has been sent\n", a);
		n++;
	}
	receive("receiver", a);
	if (strcmp(a, "ok") != 0)
	{
		printf("Not be committed,Message should be resended!\n");/*接收進程沒確認,需重新發送消息*/
		goto loop;
	}
	else
        {
                printf("Committed,Communication is finished!\n"); /*發送者得到接收者的確認,通信結束*/
        }
}

void receiver(void)         /* 接受線程的外部標識符的指針 */
{
	int i;
	int j;
	int size;
	char b[10];
	for(i=0; i<10; i++)
	{
		b[0] = 0;
		while((size=receive("sender", b)) == -1);
		{
                        printf("receiver: Message is received--");/*已接收到消息--*/
		}
		for(j=0; j<size; j++)
		{
			putchar(b[j]);
		}
		printf("\n");
	}
	strcpy(b, "ok");
	send("sender", b, 3);/* 發送確認消息 */
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章