UVa 210 并行程序模拟 (Concurrency Simulator)

本题需要你模拟一些简单程序,每一个程序有以下5种指令:

  • var = val 给变量赋值,简单起见保证变量名为一个字母,变量为所有进程共用,并且初始为0,保证val是不大于100的正整数;
  • print var 输出变量var;
  • lock 对所有变量申请独占访问 (不影响赋值和打印)
  • unlock 解除独占访问
  • end 结束程序

以上指令分别耗时t1,t2,t3,t4,t5的时间,一开始进程按照输入顺序依次插入到等待队列中,每次从等待队列队首选择一个进程执行。每个进程有一个配额(限定时间)Q,当配额用完时,该进程会在执行完当前语句后立即被插入到一个等待队列尾部中。
但是lock语句和unlock语句会改变进程的执行顺序。当一个程序执行了lock语句,其他进程再执行到lock语句时会被立即插入到一个阻止队列队尾,当程序执行到unlock语句时,阻止队列的队首的第一个进程会被立即插入到等待队列队首。
程序按输入顺序编号为(1-5)

要点:
1.Any instruction currently being
executed when the time quantum expires will be allowed to complete.
语句一旦执行了,就一定可以完成,
即不存在时间只剩下1s 但是执行一个需要2s的语句 执行一半的情况,一定会将这需要2s的语句执行完毕
2.阻止队列会插入到等待队列的队首
提示使用双端队列 deque
3.等待队列为空,阻止队列也一定为空,因为lock配套unlock,lock进去的也配套unlock,最后阻止队列一定会为空

代码:

#include<iostream>
#include<queue>
#include<string>
#include<sstream>
#include<cstring>
using namespace std;

int Lockid = 0;     //0表示没lock 正整数表示成功执行lock的程序
int var[26];

struct Program {
	int id;
	int line;       //行数
	int nowLine;    //当前行数
	string s[30];   //程序
};

deque<Program> waitQ;   //等待队列
queue<Program> blockQ;  //阻止队列

int main() {
	ios::sync_with_stdio(false);
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	int T;
	cin >> T;
	int kase = 0;
	while (T--) {
		if (kase++) {
			cout << endl;
		}
		// 数量 赋值语句 打印 LOCK UNLOCK END 时间
		memset(var, 0, sizeof(var));
		int t[6];
		int n, Q;
		cin >> n;
		for (int i = 1; i <= 5; i++) cin >> t[i];
		cin >> Q;

		//完成输入
		for (int i = 1; i <= n; i++) {
			Program p;
			string statement;
			int line = 0;
			p.id = i;
			p.nowLine = 0;
			while (cin >> statement) {
				string command;
				//赋值语句
				if (statement.length() == 1) {
					char ignoreCh;
					cin >> ignoreCh;
					int constValue;
					cin >> constValue;
					char buf[10];
					sprintf(buf, "1 %c %d", statement[0], constValue);
					command = buf;
				}
				else if (statement == "print") {
					char var;
					cin >> var;
					char buf[10];
					sprintf(buf, "2 %c", var);
					command = buf;
				}
				else if (statement == "lock") {
					command = "3";
				}
				else if (statement == "unlock") {
					command = "4";
				}
				else if (statement == "end") {
					command = "5";
				}
				//cout << command << endl;
				line++;
				p.s[line] = command;
				if (command == "5")
					break;
			}
			p.line = line;
			waitQ.push_back(p);
		}

		//处理

		while (!waitQ.empty()) {
			int time = Q;
			Program p;
			p = waitQ.front();
			waitQ.pop_front();
			bool flag = true;
			while (time > 0) {
				p.nowLine++;
				string s = p.s[p.nowLine];
				if (s[0] == '5') {
					break;
				}
				if (s[0] == '4') {
					Lockid = 0;
					if (!blockQ.empty()) {
						waitQ.push_front(blockQ.front());
						blockQ.pop();
					}
					time -= t[4];
				}
				if (s[0] == '3') {
					if (Lockid == 0)
					{
						Lockid = p.id;
						time -= t[3];
					}
					else {
						p.nowLine--; //没执行成功
						blockQ.push(p);
						flag = false;
						break;
					}
				}
				if (s[0] == '2') {
					time -= t[2];
					cout << p.id << ": " << var[s[2] - 'a'] << endl;
				}
				if (s[0] == '1') {
					time -= t[1];
					stringstream ss(s);
					int ignoreInt, needInt;
					char ch;
					ss >> ignoreInt >> ch >> needInt;
					var[ch - 'a'] = needInt;
				}
			}
			if (p.nowLine != p.line && flag) {
				waitQ.push_back(p);
			}
		}
	}
}

总结:
1.输入可能处理的有点麻烦
2.双端队列的使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值