UVa210 並行程式模擬

2022-07-10 05:21:10 字數 4016 閱讀 6655

重點在於字串處理和雙端佇列的實現,一般的佇列是隊首出隊,隊尾入隊。

題目的情景是,當乙個程序解除上鎖時,處於阻止佇列隊首的程序直接插入到等待佇列的隊首。

處理輸入的時候,將每個程序作為乙個結構體,裡面維護當前程序執行到第幾條指令,當前程序包含的指令,每條指令對應的型別,程序id,以及該程序包含幾條指令。在輸入的時候就要把這些資訊處理好。

等待佇列和阻止佇列存的都是程序id號,而不是指令,指令的執行是具有併發性的。

初始將程序id按順序乙個乙個推進等待佇列。

對於每乙個執行態的程序,都有時間片的限制,這個quantum配額是統一。執行時,按照fifo將隊首程序提為running狀態,執行指令要接著之前的進度往下執行,而且根據指令的不同,每條指令所需時間不同,還要採取不同的措施:

如果是賦值,不僅占用時間,還要更改相應變數的值,同時,因為是以字串形式給出的這個值,要有乙個不斷*10獲得這個數值的處理;

如果是輸出,則占用時間並把對應變數的值輸出;

如果是上鎖,則要看當前是否已經有程序上了鎖,因此維護乙個相對於執行過程的全域性變數lock_situation,如果沒有程序已經拿了鎖,那麼當前程序就可以上鎖,並修改lock_situation,否則,就將該變數送入阻止佇列,如果當前程序還有時間片剩餘,也只能浪費;

如果是解鎖,就要還原lock_situation變數,判斷阻止佇列是否為空,如果不為空,就要把阻止佇列的隊首出隊,插入到等待佇列的隊首;

如果是結束,就不要再把這個程序插入等待佇列了。所有指令都要記住更新程序執行到第幾條指令。

因為程序去了阻止佇列或者所有指令執行完畢就不會再去等待佇列,所以每個程序提上running態的時候都維護兩個標誌變數to_block和to_end,以判斷這一輪執行完後還要不要再把程序塞進等待佇列。

從隊首插入要注意,一般的迴圈佇列front指向的隊首元素的前乙個位置,這個位置永遠不佔元素,所以在隊首插入的時候應該先放值再移動隊首指標。

一定注意佇列max_size和開闢陣列大小的統一。不能開queue[20],但是max_size卻設成1000,這樣做就會出現奇怪現象:因為越界,碰到了別人的地盤,值無緣無故改變了 。

判空判滿的條件要爛熟於心,即使不記得,也可以自己在紙上進行推理。

題目的input和sample input不相符合,第乙個整數是整個測試用例數,但是sample input並沒有給出來。

這道題目就是多個基本知識的綜合,要有耐心,並能乙個部分乙個部分地寫好。

// 值無緣無故改變是因為越界了,碰到了別人的地盤 

// 佇列開的大小要和maxsize匹配

#include #include #include // 最多10個程式,每個程式不超過25條指令

using namespace std;

int programs = 0; // 程式數

int assign_unit = 0;

int output_unit = 0;

int lock_unit = 0;

int unlock_unit = 0;

int end_unit = 0;

int quantum = 0;

int value[30] = ; // 26個變數的值

int front_wait = 0, rear_wait = 0;

int maxsize = 1000;

//int wait_queue[20] = ; // 等待佇列

int wait_queue[1000] = ;

int front_block = 0, rear_block = 0;

//int block_queue[20] = ; // 阻止佇列

int block_queue[1000] = ;

typedef struct programprogram;

program program[15] = ;

void init()

inline int is_blank(char c)

void test_input()

printf("\n");

} return;

}int enque_rear(int which, int x)

rear_wait = (rear_wait + 1) % maxsize;

wait_queue[rear_wait] = x;

} else

rear_block = (rear_block + 1) % maxsize;

block_queue[rear_block] = x;

} return 1;

}int enque_front(int which, int x)

// front指向的是隊頭元素的前乙個

wait_queue[front_wait] = x;

front_wait = (front_wait - 1) % maxsize;

} else

block_queue[front_block] = x;

front_block = (front_block - 1) % maxsize;

} return 1;

}int deque(int which)

front_wait = (front_wait + 1) % maxsize;

return wait_queue[front_wait];

} else

front_block = (front_block + 1) % maxsize;

return block_queue[front_block]; }}

int main() else

scanf("%d", &programs);

scanf("%d%d%d%d%d%d", &assign_unit, &output_unit, &lock_unit, &unlock_unit, &end_unit, &quantum);

init();

int program = 1;

char temp[100] = ;

while (fgets(temp, 101, stdin) != null)

char *p = temp;

while (is_blank(*p))

if ((*p) == '\0')

int cur_state = program[program].cnt;

strcpy(program[program].statement[cur_state], temp);

if (strchr(temp, '=') != null) else if (temp[0] == 'p') else if (temp[0] == 'l') else if (temp[0] == 'u') else if (strcmp(temp, "end") == 0)

program[program].cnt++;

if (program[program].type[cur_state] == 5) }}

// test_input();

for (int i = 1; i <= programs; i++)

int lock_situation = 0;

while (front_wait != rear_wait)

if (program[cur_id].statement[cur_statement][6] != 0)

value[character-'a'] = temp;

program[cur_id].cur_end++;

} else if (cur_type == 2) else if (cur_type == 3) else

} else if (cur_type == 4)

} else if (cur_type == 5)

} if (to_block == 1 || to_end == 1)

if (program[cur_id].cur_end != program[cur_id].cnt)

} }return 0;

}

例題6 1 並行程式模擬(deque的使用)

例題6 1 並行程式模擬 題意 給定n個程式,每種程式有五種操作,分別為 var constant 賦值 print var 列印 lock,unlock,end 變數用小寫字母表示,初始化為0,為程式所公有 乙個程式裡對某個變數修改可以會影響其他程式裡的這個變數 常數小於100 也就是說最多兩位數...

併發程式與並行程式

併發程式是指可以被同時發起執行的程式 並行程式被設計成可以在並行的硬體上執行的併發程式。併發程式代表了所有可以實現並發行為的程式,它是乙個寬泛的概念,其中包含了並行程式。inter process communication 程序間通訊 go支援的ipc方法有管道 訊號和socket.程序 我們把乙...

Java並行程式基礎

程序是計算機中的程式關於某資料集合上的一次運動活動,是系統進行資源分配的基礎單位。程序是執行緒的容器。程式是指令 資料及其組織形式的描述,程序是程式的實體。執行緒的所有狀態都在thread的state列舉中 public enum state t1.start 也可以使用runnable介面來實現相...