UVA210 concurrency simulator (双向队列 & 模拟)

 

 

concurrency simulator

 

 

Programs executed concurrently on a uniprocessor system appear to be executed at the same time, but in reality the single CPU alternates between the programs, executing some number of instructions from each program before switching to the next. You are to simulate the concurrent execution of up to ten programs on such a system and determine the output that they will produce.

 

The program that is currently being executed is said to be running, while all programs awaiting execution are said to be ready. A program consists of a sequence of no more than 25 statements, one per line, followed by an end statement. The statements available are listed below.

 

 

tex2html_wrap66tex2html_wrap68

 

Each statement requires an integral number of time units to execute. The running program is permitted to continue executing instructions for a period of time called its quantum. When a programÕs time quantum expires, another ready program will be selected to run. Any instruction currently being executed when the time quantum expires will be allowed to complete.

 

Programs are queued first-in-first-out for execution in a ready queue. The initial order of the ready queue corresponds to the original order of the programs in the input file. This order can change, however, as a result of the execution of lock and unlock statements.

 

The lock and unlock statements are used whenever a program wishes to claim mutually exclusive access to the variables it is manipulating. These statements always occur in pairs, bracketing one or more other statements. A lock will always precede an unlock, and these statements will never be nested. Once a program successfully executes a lock statement, no other program may successfully execute a lock statement until the locking program runs and executes the corresponding unlock statement. Should a running program attempt to execute a lock while one is already in effect, this program will be placed at the end of the blocked queue. Programs blocked in this fashion lose any of their current time quantum remaining. When an unlock is executed, any program at the head of the blocked queue is moved to the head of the ready queue. The first statement this program will execute when it runs will be the lock statement that previously failed. Note that it is up to the programs involved to enforce the mutual exclusion protocol through correct usage of lock andunlock statements. (A renegade program with no lock/unlock pair could alter any variables it wished, despite the proper use oflock/unlock by the other programs.)

 

Input

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

 

The first line of the input file consists of seven integers separated by spaces. These integers specify (in order): the number of programs which follow, the unit execution times for each of the five statements (in the order given above), and the number of time units comprising the time quantum. The remainder of the input consists of the programs, which are correctly formed from statements according to the rules described above.

All program statements begin in the first column of a line. Blanks appearing in a statement should be ignored. Associated with each program is an identification number based upon its location in the input data (the first program has ID = 1, the second has ID = 2, etc.).

 

Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

 

Your output will contain of the output generated by the print statements as they occur during the simulation. When a print statement is executed, your program should display the program ID, a colon, a space, and the value of the selected variable. Output from separate print statements should appear on separate lines.

 

A sample input and correct output are shown below.

 

Sample Input

 

1

3 1 1 1 1 1 1
a = 4
print a
lock
b = 9
print b
unlock
print b
end
a = 3
print a
lock
b = 8
print b 
unlock
print b
end
b = 5
a = 17
print a
print b
lock
b = 21
print b
unlock
print b
end

 

Sample Output

 

1: 3
2: 3
3: 17
3: 9
1: 9
1: 9
2: 8
2: 8
3: 21

3: 21

 

 

 

题目主要难在理解上,说下题意:有n个程序,每个程序都有5种状态,分别是 =,print,lock,unlock,end,每个状态都有一个执行的单位时间,分别是t[0],t[1],t[2],t[3],t[4],n个程序中每个程序执行的时间都不超过Q。其中所有变量(比如a,b,c等)都是全局变量,有一个地方变量的值发生改变则全局的变量值都会发生改变。并且程序如果变成lock的状态时,则只能运行该程序段,而后遇到的其他程序则都要放到阻塞队列中去;如果遇到unlock,则要把阻塞队列队首元素放到就绪队列中。

 

 

#include <iostream>
#include <cstdio>
#include <deque>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1100;
int t[5],n,lim,tt;//lim表示每个个程序每次可以执行的单位时间
bool lock;     //判断当前是否是上锁
queue<int > qw; //阻塞队列
deque<int > qr; //等待队列
vector<string> prg[maxn];//存储n个程序
int var[maxn],q[maxn];//var[]记录变量a的值,q[]记录是第i个程序中的第几个程序段

void solve(int x){
    int tx = lim;
    while(tx > 0){//还在该程序的有效执行时间之内
        string s = prg[x][q[x]]; //获取该程序段
        if(s[2] == '='){
            tx -= t[0];
            int v = s[4] - '0';
            if(s.size() == 6) v = v * 10 + (s[5] - '0');
            var[s[0] - 'a'] = v;
        }
        else if(s[2] == 'i'){
            tx -= t[1];
            printf("%d: %d\n",x,var[s[6] - 'a']);
        }
        else if(s[2] == 'c'){
            tx -= t[2];
            if(lock){//当前状态已经是锁的状态,其他程序则要放到阻塞队列
                qw.push(x);
                return ;
            }
            else lock = true;
        }
        else if(s[2] == 'l'){//开锁,取阻塞队列队首元素放到就绪队列队首
            tx -= t[3];
            lock = false;
            if(!qw.empty()){
                qr.push_front(qw.front());
                qw.pop();
            }
        }
        else return ;
        q[x] ++;   //表示该程序中的某段执行完毕,要执行下一段
    }
    qr.push_back(x);  //ID为x的程序运行结束后入就绪队列尾
}

int main(){
    scanf("%d",&tt);
    while(tt --){
        scanf("%d",&n);
        for(int i = 0; i < 5; i ++) scanf("%d",&t[i]);
        scanf("%d",&lim);
        string s;
        for(int i = 1; i <= n; i ++){
            prg[i].clear();
            while(1){
                getline(cin,s);//输入一行
                if(s == "") continue;
                prg[i].push_back(s);
                if(s == "end") break;
            }
            qr.push_back(i);  //把程序的ID入就绪队列
        }
        memset(var,0,sizeof(var));
        memset(q,0,sizeof(q));
        while(!qr.empty()){
            int x = qr.front();
            qr.pop_front();
            solve(x);
        }
        if(tt) printf("\n");
    }
    return 0;
}

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值