我用C编的一个PCB的一个时间片、优先级的多线程的程序,希望高手看看那里错了?

时间:2021-10-11 08:33:54

#include "stdio.h"
#include "stdlib.h"
#define MAXPROCNUM 5
#define WAIT 0
#define RUN 1
#define  FINISH 2
#define TIME 0
#define PRIO 1

typedef struct  //define the struct of PCB
{
 int id;
 int pri;
 int cputime;
 int alltime;
 int next;
 int state;
}PROC;
PROC procchain[MAXPROCNUM];
FIlE *f; //define file point v,f point to the opened file
int run,head,tail;

void insert(int q)
{
 int p,s;
 p=head;
 s=procchain[head].next;
 while (procchain[q].pri < procchain[s].pri && s)
 {
 p=s;
 s=procchain[s].next;
 }
 procchain[p].next=q;
 procchain[q].next=s;
}

void insert2() //take one process to the rear
{
procchain[tail].next=run;
tail=run;
procchain[run].next=0;
}

void print()
{
int i,p;
for(i=0;i<40;i++)
{
fprintf(*f,"=");
}
fprintf(f,"\n---------------------------------------");
fprintf(f,"Running PROC    Waiting Queng\n");
fprintf(f,"%5d      ",procchain[run].id);
p=head;
while(p)
{
fprint(*f,"%5d",p);
p=procchain[p].next;
}
fprintf(f,"\n");
for(i=0;i<40;i++)
fprintf(f,"=");

fprintf(f,"\n ID               ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].id);


fprintf(f,"\n PIRORITY              ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].pri);

fprintf(f,"\n CPUTIME              ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].cputime);

fprintf(f,"\n ALLTIME              ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].alltime);

fprintf(f,"\n STATE              ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].state);

fprintf(f,"\n NEXT             ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].next);

fprintf(f,"\n ----------------------------------");
for(i=0;i<40;i++)
fprintf(f,"=");
    printf(f,"\n");
}
void init(int alg)
{
int i;
randomize();
head=0;
if(alg==PRIO)
for (i=1;i<MAXPROCNUM;i++)    //Priority
{
procchain[i].id=i;
procchain[i].pri=(random(100)+1)%4+1;
procchain[i].cputime=0;
procchain[i].alltime=(random(100)+1)%7+1;
procchain[i].state=WAIT;
procchain[i].next=0;
if ((procchain[i].pri<procchain[head].pri) &&(head!=0))
insert(procchain[i].id);
else 
{
procchain[i].next=head;
head=procchain[i].id;
}
}
else                //Time   Round
{
for(i=1;i<MAXPROCNUM;i++)
{
procchain[i].id=i;
    procchain[i].pri=(random(100)+1)%3+1;
procchain[i].cputime=0;
procchain[i].alltime=(random(100)+1)%6+1;
procchain[i].state=WAIT;
procchain[i].next=(i+1)%(MAXPROCNUM+1);
}
head=1;
tail=MAXPROCNUM;
procchain[MAXPROCNUM].next=0;
}
run=head;
procchain[run].state=RUN;
head=procchain[head].next;
fprint();
}


void prisch()
{
while(run)
{
procchain[run].cputime++;
procchain[run].pri=procchain[run].pri-3;
if(procchain[run].alltime>0)
procchain[run].alltime--;
if(procchain[run].alltime<=0)
{
procchain[run].state=FINISH;
procchain[run].next=0;
if(head)
{
run=head;
procchain[run].state=RUN;
head=procchain[head].next;
}
else
{
procchain[0].id=procchain[run].id;
run=0;
}
}
else
{
if(head&&procchain[run].pri<procchain[head].pri)
{
procchain[run].state=WAIT;
insert(run);
run=head;
procchain[run].state=RUN;
head=procchain[head].next;
}
fprint();
}

}

main()
{
        int alg , i;
do
        {
        printf("TYPE THE ALGORITHM (0 FOR ROUND ROBIN AND I FOR FRIORITY)\n");
printf("input 0 or 1:");
scanf("%d",&alg);
}
while(alg!=PRIO && alg!=TIME);
if(alg==TIME)
{
                f=fopen("A:\\TIME.TEXT","w");
        if(f==NULL) exit(1);
                 fprintf(f,"OUTPUT OF ROUND ROBIN\n");
         init(TIME);
        timesch();
}
else
{
                f=fopen("A:\\PRIORITY.TEXT","w");
         if(f==NULL)exit(1)
                fprintf(f,"OUTPUT OF PRIORITY\n")
         int(PRIO);
         prisch();

}
         for(i=0;i<40;i++);
{
                fprintf(f,"=");
                }
fprintf(f,"\n");
fprintf(f,"SYSTEM FINISHED\n");
fclose(f);
}


15 个解决方案

#1


我这里用了file的文件导入,但不知道那里错了,无论如何也到不进来!

#2


那位雄台可以,给我一个C++版本的升级版?

小弟有礼了!

#3


c++版本的升级?
你指的是什么?

#4


就是用c++把这段用C编程序实现阿!
那位高手可以帮忙阿?

构架一个类!

#5


顶!

#6


up

#7


我只是一个大三的学生,希望能有高手指点我啊!

#8


#include "stdio.h"
#include "stdlib.h"
#define MAXPROCNUM 5
#define WAIT 0
#define RUN 1
#define  FINISH 2
#define TIME 0
#define PRIO 1

typedef struct  //define the struct of PCB
{
 int id;
 int pri;
 int cputime;
 int alltime;
 int next;
 int state;
}PROC;
PROC procchain[MAXPROCNUM];
FILE *f;//define file point v,f point to the opened file
int run,head,tail;

void insert(int q)
{
 int p,s;
 p=head;
 s=procchain[head].next;
 while (procchain[q].pri < procchain[s].pri && s)
 {
 p=s;
 s=procchain[s].next;
 }
 procchain[p].next=q;
 procchain[q].next=s;
}

void insert2() //take one process to the rear
{
procchain[tail].next=run;
tail=run;
procchain[run].next=0;
}

void print()
{
int i,p;
for(i=0;i<40;i++)
{
fprintf(f,"=");
}
fprintf(f,"\n---------------------------------------");
fprintf(f,"\nRunning PROC    Waiting Queng\n");
fprintf(f,"%5d      ",procchain[run].id);
p=head;
while(p)
{
fprintf(f,"%5d",p);
p=procchain[p].next;
}
fprintf(f,"\n");
for(i=0;i<40;i++)
fprintf(f,"=");

fprintf(f,"\n ID                    ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].id);


fprintf(f,"\n PIRORITY              ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].pri);

fprintf(f,"\n CPUTIME               ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].cputime);

fprintf(f,"\n ALLTIME               ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].alltime);

fprintf(f,"\n STATE                 ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].state);

fprintf(f,"\n NEXT                  ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].next);

fprintf(f,"\n ----------------------------------");
for(i=0;i<40;i++)
    fprintf(f,"=");
printf("\n");
}

void init(int alg)
{
int i;
randomize();
head=0;
if(alg==PRIO){
for (i=1;i<MAXPROCNUM;i++)    //Priority
{
procchain[i].id=i;
procchain[i].pri=(random(100)+1)%4+1;
procchain[i].cputime=0;
procchain[i].alltime=(random(100)+1)%7+1;
procchain[i].state=WAIT;
procchain[i].next=0;
if ((procchain[i].pri<procchain[head].pri) &&(head!=0))
   insert(procchain[i].id);
else
{
procchain[i].next=head;
head=procchain[i].id;
}
}}
else                //Time   Round
{
for(i=1;i<MAXPROCNUM;i++)
{
   procchain[i].id=i;
   procchain[i].pri=(random(100)+1)%3+1;
   procchain[i].cputime=0;
   procchain[i].alltime=(random(100)+1)%6+1;
   procchain[i].state=WAIT;
   procchain[i].next=(i+1)%(MAXPROCNUM+1);
}
head=1;
tail=MAXPROCNUM;
procchain[MAXPROCNUM].next=0;
}
run=head;
procchain[run].state=RUN;
head=procchain[head].next;
fprintf(f,"init finish\n");
}

void prisch()
{
    while(run)
    {
    procchain[run].cputime++;
    procchain[run].pri=procchain[run].pri-3;
    if(procchain[run].alltime>0)
procchain[run].alltime--;
    if(procchain[run].alltime<=0)
    {
     procchain[run].state=FINISH;
     procchain[run].next=0;
      if(head)
      {
       run=head;
       procchain[run].state=RUN;
       head=procchain[head].next;
       }else{
       procchain[0].id=procchain[run].id;
       run=0;
      }
   }else{
    if(head&&procchain[run].pri<procchain[head].pri)
    {
      procchain[run].state=WAIT;
      insert(run);
      run=head;
      procchain[run].state=RUN;
      head=procchain[head].next;
     }
     }
     print();
  }
}
void timesch()
{
   fprintf(f,""not define function timesch()");
}
void main()
{
int alg , i;

   do{
printf("TYPE THE ALGORITHM (0 FOR ROUND ROBIN AND I FOR FRIORITY)\n");
printf("input 0 or 1:");
scanf("%d",&alg);
     }while(alg!=PRIO && alg!=TIME);
  f=fopen("A:\\TIME.TEXT","w");
  if(f==NULL) exit(1);
  if(alg==TIME)
 {
 fprintf(f,"OUTPUT OF ROUND ROBIN\n");
 init(TIME);
 timesch();
}
else
{
fprintf(f,"OUTPUT OF PRIORITY\n");
init(PRIO);
prisch();

}
 for(i=0;i<40;i++);
   fprintf(f,"=");
 fprintf(f,"\n");
 fprintf(f,"SYSTEM FINISHED\n");
 fclose(f);
}

  看在你这么喜欢c语言的分上,帮你一次!要继续努力呀! 
  这个程序有个还有一个不好的地方,就是每次运行后,你的每个所谓的“小进程”的优先级就要下降3级,以至于会进入负值,没有那个os会是这样的。一个解决的办法就是设置一个变量,暂时将他的优先级降下来,等n(自己设定在2-4之间)个运行周期后再恢复到原来的优先级。还有,cputime这个变量和alltime重合,只不过,一个加,一个减,没必要。

#9


正在写一个线程池,不是模拟,而是真实的线程调度,
涉及到自己的栈管理和虚拟线程的轮转。
用的C++和嵌入式汇编来做的。

还有一个难点就是如何截获被挂起线程的eip……然后改变他,使得重新运转后可以执行自己希望他到达的地方。

不用GetThreadContext和SetThreadContext函数的方法。
(98系统,或者NT系统,普通用户权限)

如果有知道的,希望指教。
email:    nicknide@163.com
共同交流。

#10


__declspec (naked)
int
__cdecl
UseHeapStackByStdCal(void* /* opt */, //操作函数,int (__stdcall*)(void*)
 void* /* argment */,      //操作函数的参数
 void* /* stackBuf */ ,      //私有栈起点
 unsigned int /* stackBufSize */, //私有栈大小
 void (__cdecl* /* callback */)(unsigned int /* ebp */,unsigned int /* esp */)
                                        //回调函数,用来告诉用户原始的ebp和esp地址。
 )
__BEGIN_NAKED__
mov eax,ebp
mov ecx,esp

mov ebp,[esp + 0xC]
add ebp,[esp + 0x10]
mov esp,ebp
push ecx
push eax

mov eax,[ecx+0x14]
test eax,eax
jz lag_next_
push esp
push ebp
call eax
sub esp,8
mov ecx,[esp+4]
lag_next_:

push [ecx+0x8]
mov eax, [ecx+0x4]
call eax

pop ebp
pop esp
ret
__END_NAKED__

以上是我写的,使用私有栈的代码,.net上编译
其中有2个宏:
#define __BEGIN_NAKED__  {__asm{
#define __END_NAKED__     }}


写出来的目的,是希望有朋友能够回答对我上面那个问题
我不是随便说说而已哦。

#11


mark,等我喊值班室的兄弟去看,呵呵

#12


没法子,我对c++知道的不多。不能帮你。不过如果你把你的意思详细说出来,说不定我可以帮你看看

#13


呵呵,谢谢老迈和各位的关注了。

当初提出的目的是以为9x系统不提供GetThreadContext操作(我的MSDN 03 上面只说 XP和2000系列有这个函数,没有说9x系统也有,还是看得老版本的MSDN发现有的),所以得自己写,如果9x系统有,则没其他办法的时候,就这样用得了(还得先测试是不是2000系统中必须是DEBUG USER权限才能够运行),先挂起,然后保存当前状态,最后修改执行点,到其他地址,然后恢复执行,呵呵。

不过没有试过,不知道能不能欺骗成功(最近用JAVA写一个聊天室,虽然本人JAVA差劲到连有些语法都不了解,但是总还不能误了我的名声啊,所以这一周都在捣持那个东西,写一个基于分布式的聊天平台。)

#14


up

#15


帮顶吧
代码看得头昏昏得

#1


我这里用了file的文件导入,但不知道那里错了,无论如何也到不进来!

#2


那位雄台可以,给我一个C++版本的升级版?

小弟有礼了!

#3


c++版本的升级?
你指的是什么?

#4


就是用c++把这段用C编程序实现阿!
那位高手可以帮忙阿?

构架一个类!

#5


顶!

#6


up

#7


我只是一个大三的学生,希望能有高手指点我啊!

#8


#include "stdio.h"
#include "stdlib.h"
#define MAXPROCNUM 5
#define WAIT 0
#define RUN 1
#define  FINISH 2
#define TIME 0
#define PRIO 1

typedef struct  //define the struct of PCB
{
 int id;
 int pri;
 int cputime;
 int alltime;
 int next;
 int state;
}PROC;
PROC procchain[MAXPROCNUM];
FILE *f;//define file point v,f point to the opened file
int run,head,tail;

void insert(int q)
{
 int p,s;
 p=head;
 s=procchain[head].next;
 while (procchain[q].pri < procchain[s].pri && s)
 {
 p=s;
 s=procchain[s].next;
 }
 procchain[p].next=q;
 procchain[q].next=s;
}

void insert2() //take one process to the rear
{
procchain[tail].next=run;
tail=run;
procchain[run].next=0;
}

void print()
{
int i,p;
for(i=0;i<40;i++)
{
fprintf(f,"=");
}
fprintf(f,"\n---------------------------------------");
fprintf(f,"\nRunning PROC    Waiting Queng\n");
fprintf(f,"%5d      ",procchain[run].id);
p=head;
while(p)
{
fprintf(f,"%5d",p);
p=procchain[p].next;
}
fprintf(f,"\n");
for(i=0;i<40;i++)
fprintf(f,"=");

fprintf(f,"\n ID                    ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].id);


fprintf(f,"\n PIRORITY              ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].pri);

fprintf(f,"\n CPUTIME               ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].cputime);

fprintf(f,"\n ALLTIME               ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].alltime);

fprintf(f,"\n STATE                 ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].state);

fprintf(f,"\n NEXT                  ");
for(i=1;i<MAXPROCNUM;i++)
fprintf(f,"%5d",procchain[i].next);

fprintf(f,"\n ----------------------------------");
for(i=0;i<40;i++)
    fprintf(f,"=");
printf("\n");
}

void init(int alg)
{
int i;
randomize();
head=0;
if(alg==PRIO){
for (i=1;i<MAXPROCNUM;i++)    //Priority
{
procchain[i].id=i;
procchain[i].pri=(random(100)+1)%4+1;
procchain[i].cputime=0;
procchain[i].alltime=(random(100)+1)%7+1;
procchain[i].state=WAIT;
procchain[i].next=0;
if ((procchain[i].pri<procchain[head].pri) &&(head!=0))
   insert(procchain[i].id);
else
{
procchain[i].next=head;
head=procchain[i].id;
}
}}
else                //Time   Round
{
for(i=1;i<MAXPROCNUM;i++)
{
   procchain[i].id=i;
   procchain[i].pri=(random(100)+1)%3+1;
   procchain[i].cputime=0;
   procchain[i].alltime=(random(100)+1)%6+1;
   procchain[i].state=WAIT;
   procchain[i].next=(i+1)%(MAXPROCNUM+1);
}
head=1;
tail=MAXPROCNUM;
procchain[MAXPROCNUM].next=0;
}
run=head;
procchain[run].state=RUN;
head=procchain[head].next;
fprintf(f,"init finish\n");
}

void prisch()
{
    while(run)
    {
    procchain[run].cputime++;
    procchain[run].pri=procchain[run].pri-3;
    if(procchain[run].alltime>0)
procchain[run].alltime--;
    if(procchain[run].alltime<=0)
    {
     procchain[run].state=FINISH;
     procchain[run].next=0;
      if(head)
      {
       run=head;
       procchain[run].state=RUN;
       head=procchain[head].next;
       }else{
       procchain[0].id=procchain[run].id;
       run=0;
      }
   }else{
    if(head&&procchain[run].pri<procchain[head].pri)
    {
      procchain[run].state=WAIT;
      insert(run);
      run=head;
      procchain[run].state=RUN;
      head=procchain[head].next;
     }
     }
     print();
  }
}
void timesch()
{
   fprintf(f,""not define function timesch()");
}
void main()
{
int alg , i;

   do{
printf("TYPE THE ALGORITHM (0 FOR ROUND ROBIN AND I FOR FRIORITY)\n");
printf("input 0 or 1:");
scanf("%d",&alg);
     }while(alg!=PRIO && alg!=TIME);
  f=fopen("A:\\TIME.TEXT","w");
  if(f==NULL) exit(1);
  if(alg==TIME)
 {
 fprintf(f,"OUTPUT OF ROUND ROBIN\n");
 init(TIME);
 timesch();
}
else
{
fprintf(f,"OUTPUT OF PRIORITY\n");
init(PRIO);
prisch();

}
 for(i=0;i<40;i++);
   fprintf(f,"=");
 fprintf(f,"\n");
 fprintf(f,"SYSTEM FINISHED\n");
 fclose(f);
}

  看在你这么喜欢c语言的分上,帮你一次!要继续努力呀! 
  这个程序有个还有一个不好的地方,就是每次运行后,你的每个所谓的“小进程”的优先级就要下降3级,以至于会进入负值,没有那个os会是这样的。一个解决的办法就是设置一个变量,暂时将他的优先级降下来,等n(自己设定在2-4之间)个运行周期后再恢复到原来的优先级。还有,cputime这个变量和alltime重合,只不过,一个加,一个减,没必要。

#9


正在写一个线程池,不是模拟,而是真实的线程调度,
涉及到自己的栈管理和虚拟线程的轮转。
用的C++和嵌入式汇编来做的。

还有一个难点就是如何截获被挂起线程的eip……然后改变他,使得重新运转后可以执行自己希望他到达的地方。

不用GetThreadContext和SetThreadContext函数的方法。
(98系统,或者NT系统,普通用户权限)

如果有知道的,希望指教。
email:    nicknide@163.com
共同交流。

#10


__declspec (naked)
int
__cdecl
UseHeapStackByStdCal(void* /* opt */, //操作函数,int (__stdcall*)(void*)
 void* /* argment */,      //操作函数的参数
 void* /* stackBuf */ ,      //私有栈起点
 unsigned int /* stackBufSize */, //私有栈大小
 void (__cdecl* /* callback */)(unsigned int /* ebp */,unsigned int /* esp */)
                                        //回调函数,用来告诉用户原始的ebp和esp地址。
 )
__BEGIN_NAKED__
mov eax,ebp
mov ecx,esp

mov ebp,[esp + 0xC]
add ebp,[esp + 0x10]
mov esp,ebp
push ecx
push eax

mov eax,[ecx+0x14]
test eax,eax
jz lag_next_
push esp
push ebp
call eax
sub esp,8
mov ecx,[esp+4]
lag_next_:

push [ecx+0x8]
mov eax, [ecx+0x4]
call eax

pop ebp
pop esp
ret
__END_NAKED__

以上是我写的,使用私有栈的代码,.net上编译
其中有2个宏:
#define __BEGIN_NAKED__  {__asm{
#define __END_NAKED__     }}


写出来的目的,是希望有朋友能够回答对我上面那个问题
我不是随便说说而已哦。

#11


mark,等我喊值班室的兄弟去看,呵呵

#12


没法子,我对c++知道的不多。不能帮你。不过如果你把你的意思详细说出来,说不定我可以帮你看看

#13


呵呵,谢谢老迈和各位的关注了。

当初提出的目的是以为9x系统不提供GetThreadContext操作(我的MSDN 03 上面只说 XP和2000系列有这个函数,没有说9x系统也有,还是看得老版本的MSDN发现有的),所以得自己写,如果9x系统有,则没其他办法的时候,就这样用得了(还得先测试是不是2000系统中必须是DEBUG USER权限才能够运行),先挂起,然后保存当前状态,最后修改执行点,到其他地址,然后恢复执行,呵呵。

不过没有试过,不知道能不能欺骗成功(最近用JAVA写一个聊天室,虽然本人JAVA差劲到连有些语法都不了解,但是总还不能误了我的名声啊,所以这一周都在捣持那个东西,写一个基于分布式的聊天平台。)

#14


up

#15


帮顶吧
代码看得头昏昏得