CCF-CSP题解 201903-4 消息传递接口
求并行的各个进程,且进程内部顺序执行的情况下,会不会出现“死锁”。
首先用\(%[^\n]\)将每个进程读入。最后过不了居然是因为\(str[\ ]\)开小了(悲喜交加。存储在\(<op,\ pid>[\ ]\)中,并记录每个进程的指令数\(instNum[\ ]\)。
然后就是模拟。\(instCmp[\ ]\)记录每个进程已完成的指令数,\(instBlk[\ ]\)记录每个进程是否阻塞,\(numCmp,\ numBlk\)分别是完成和阻塞的进程数。主要思想是:每次执行到某条指令阻塞,然后执行下条指令并循环。判断是否阻塞,就是看\(<op, pid>\)对应的\(pid\)进程当前已完成的指令是否有下一条指令,以及下一条指令是否与之配对。
#include <bits/stdc++.h>
const int maxn = 10000;
using namespace std;
struct tInst
{
int op;
int pid;
};
tInst inst[maxn+10][10];
int instNum[maxn+10];
int instCmp[maxn+10];
int instBlk[maxn+10];
int numCmp, numBlk;
int main ()
{
int T, n;
scanf("%d%d", &T, &n);
getchar();
while (T--)
{
memset(instNum, 0, sizeof(instNum));
for (int i = 0; i <= n - 1; i++)
{
char str[100];
scanf("%[^\n]", str + 1);
getchar();
for (int j = 1, op = 0, pid = 0; ; j++)
{
if (str[j] == 'R')
op = 0;
else if (str[j] == 'S')
op = 1;
else if (str[j] >= '0' && str[j] <= '9')
pid = pid * 10 + str[j] - '0';
else if (str[j] == ' ')
{
inst[i][++instNum[i]].op = op;
inst[i][instNum[i]].pid = pid;
pid = 0;
}
else
{
inst[i][++instNum[i]].op = op;
inst[i][instNum[i]].pid = pid;
break;
}
}
}
memset(instCmp, 0, sizeof(instCmp));
memset(instBlk, 0, sizeof(instBlk));
numCmp = numBlk = 0;
int x = 0;
while (numCmp + numBlk != n)
{
while (instCmp[x] != instNum[x] && !instBlk[x])
{
int y = instCmp[x] + 1;
int op = inst[x][y].op, pid = inst[x][y].pid;
int xx = pid;
if (instCmp[xx] != instNum[xx])
{
int yy = instCmp[xx] + 1;
if (op + inst[xx][yy].op == 1 && x == inst[xx][yy].pid)
{
instCmp[x] ++; instCmp[xx] ++;
if (instCmp[x] == instNum[x])
numCmp ++;
if (instCmp[xx] == instNum[xx])
numCmp ++;
if (instBlk[xx])
{
instBlk[xx] = 0;
numBlk --;
}
}
else
{
instBlk[x] = 1;
numBlk ++;
}
}
else
{
instBlk[x] = 1;
numBlk ++;
}
}
x = (x + 1) % n;
}
if (numCmp == n)
printf("0\n");
else
printf("1\n");
}
return 0;
}