提示:文章
前言
前期疑问:
本文目标:
进程管理
一、背景
二、题目
题目
【软件认证】统计进程管理的设备
一款设备管理软件系统,管理的设备类型deviceType
共有无线、数通、接入3 种类型(值分别为1、2、3),针对每种类型的设备都有一个进程组进行管理(编号对应也为1、2、3)。每个进程组均有
procNum
个进程(进程 procId 从 0 开始依次编号);每个进程可管理多个设备,进程的内存资源上限均为maxMemSize
,每新增管理一个设备都会消耗某进程的内存资源。请完成该系统如下功能:
DeviceMgtSystem(int procNum, int maxMemSize)
—初始化:每个进程组创建procNum
个进程,每个进程的内存上限为maxMemSize
。createDevice(int deviceId, int deviceType, int memSize)
—在 deviceType 对应进程组内,按「负载均衡规则」选择一个进程,创建设备 deviceId 进行管理,内存消耗为 memSize,创建成功返回所在进程编号;当对应进程组内所有进程的剩余内存资源都不足时,则创建失败,返回-1
。
- 「负载均衡规则」:优先选择空闲内存较多的进程;若空闲内存相同,则选择编号较小者。
- 注意:用例保证每次传入的 deviceId 均不同。
deleteDevice(int deviceId)
—删除设备 deviceId 。若存在该设备,则删除成功、释放内存,并返回true
;否则返回false
。queryDevice(int deviceType)
—返回 deviceType 对应进程组内所有设备信息的列表(或为空列表[]
):
- 设备信息格式:
[deviceId, memSize, procId]
。- 返回顺序:优先按设备所消耗的内存
memSize
降序;若有相同按设备所在的进程procId
升序;若还有相同按deviceId
升序。输入
每行表示一个函数调用,初始化函数仅首行调用一次,累计函数调用不超过 1000 次。
1 <= procNum <= 5, 100 <= maxMemSize <= 1000
1 <= deviceType <= 3, 1 <= memSize <= 100, 1 <= deviceId <= 1000输出
答题时按照函数/方法原型中的要求(含返回值)进行实现,输出由框架完成(其中首行固定输出
null
)样例1
复制输入:输入:
DeviceMgtSystem(2, 200)
createDevice(8, 1, 50)
createDevice(12, 1, 30)
createDevice(3, 1, 30)
queryDevice(1)
createDevice(15, 1, 30)
queryDevice(1)
deleteDevice(10)输出:
null
0
1
1
[[8, 50, 0], [3, 30, 1], [12, 30, 1]]
0
[[8, 50, 0], [15, 30, 0], [3, 30, 1], [12, 30, 1]]
false解释:
DeviceMgtSystem(2, 200)
// 初始化,每个进程组的进程数有 2 个,每个进程的内存上限为 200
createDevice(8, 1, 50)
// 创建设备 8,设备类型为 1,消耗内存 50。在进程组 1 中,按负载均衡规则,选择在进程 0 创建,返回 0
createDevice(12, 1, 30)
// 在进程组 1 的进程 1 上创建,返回 1
createDevice(3, 1, 30)
// 在进程组 1 中选择空闲内存多的进程 1 上创建,返回 1
queryDevice(1)
// 按设备消耗的内存降序,设备 8 排在前面;之后是设备12、3,两个设备都在进程 1 上,再按设备id升序,所以设备 3 排在前面。
// 最后输出 [[8, 50, 0], [3, 30, 1], [12, 30, 1]]
createDevice(15, 1, 30)
// 在进程组 1 的进程 0 上创建,返回 0
queryDevice(1)
// 设备 8 的消耗的内存最多,排在最前;设备 3、12、15 消耗的内存相同,由于设备 15 所在进程号为 0,排在设备3、12前面,最后输出 [[8, 50, 0], [15, 30, 0], [3, 30, 1], [12, 30, 1]]
deleteDevice(10)
// 删除设备 10,设备不存在,返回false。样例2
输入:DeviceMgtSystem(2, 100)
createDevice(18, 2, 50)
createDevice(3, 2, 30)
createDevice(12, 2, 20)
queryDevice(1)
queryDevice(2)
createDevice(15, 1, 40)
createDevice(6, 2, 30)
createDevice(19, 2, 60)
deleteDevice(18)
createDevice(26, 2, 70)
queryDevice(1)
queryDevice(2)输出:
null
0
1
1
[]
[[18, 50, 0], [3, 30, 1], [12, 20, 1]]
0
0
-1
true
0
[[15, 40, 0]]
[[26, 70, 0], [6, 30, 0], [3, 30, 1], [12, 20, 1]]解释:
DeviceMgtSystem(2, 100)
createDevice(18, 2, 50) // 在进程组 2 的进程 0 上创建
createDevice(3, 2, 30) // 在进程组 2 的进程 1 上创建
createDevice(12, 2, 20) // 按负载均衡规则,在进程组 2 的进程 1 上创建
queryDevice(1) // 未创建过设备类型 1 的设备,返回列表为空 []
queryDevice(2)
createDevice(15, 1, 40) // 在进程组 1 的进程 0 上创建
createDevice(6, 2, 30) // 进程组 2 的进程0、1空闲内存相同,按负载均衡规则,在进程 0 上创建
createDevice(19, 2, 60) // 进程组 2 的进程 0 空闲内存为 20,进程 1 空闲内存为 50,资源均不足,创建失败,返回 -1
deleteDevice(18) // 删除后,进程组 2 的进程 0 空闲内存为 70,进程 1 空闲内存为 50
createDevice(26, 2, 70) // 进程组 2 的进程 0 的空闲内存刚好够用,创建成功
queryDevice(1)
queryDevice(2)提示
// 初始化及调用参考(以 C 为例,其他语言参考):DeviceMgtSystem *sys = DeviceMgtSystemCreate(procNum, maxMemSize);int param_1 = DeviceMgtSystemCreateDevice(&sys, deviceId, deviceType, memSize);bool param_2 = DeviceMgtSystemDeleteDevice(&sys, deviceId);DeviceInfo *param_3 = DeviceMgtSystemQueryDevice(&sys, deviceType, &returnSize);DeviceMgtSystemFree(&sys)
代码框架
main.cpp文件
#include <stdlib.h>
#include <stdio.h>
#include "securec.h"
#include "solution.c"
// 以下为考题输入输出框架,此部分代码不建议改动;提交代码时请勿包含下面代码
static void SkipWs(void)
{
char c = (char)getchar();
while (c == ' ' || c == '\r' || c == '\n') {
c = (char)getchar();
}
(void)ungetc(c, stdin);
}
static void PrintDeviceInfo(const DeviceInfo *ptr)
{
printf("[");
printf("%d", ptr->deviceId);
printf(", ");
printf("%d", ptr->memSize);
printf(", ");
printf("%d", ptr->procId);
printf("]");
}
static void PrintListDeviceInfo(const DeviceInfo *value, size_t size)
{
printf("[");
for (size_t i = 0; i < size; ++i) {
PrintDeviceInfo(&value[i]);
if (i + 1 < size) { printf(", "); }
}
printf("]");
}
static void FreeListDeviceInfo(DeviceInfo *value)
{
if (!value) { return; }
free(value);
}
static bool CallCreate(DeviceMgtSystem **sys)
{
int procNum = 0;
int maxMemSize = 0;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &procNum) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ',') { break; }
if (scanf_s("%d", &maxMemSize) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
*sys = DeviceMgtSystemCreate(procNum, maxMemSize);
} while (false);
printf("null\n");
return isOk;
}
static bool CallCreateDevice(DeviceMgtSystem *sys)
{
int deviceId = 0;
int deviceType = 0;
int memSize = 0;
int returnValue = 0;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &deviceId) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ',') { break; }
if (scanf_s("%d", &deviceType) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ',') { break; }
if (scanf_s("%d", &memSize) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
returnValue = DeviceMgtSystemCreateDevice(sys, deviceId, deviceType, memSize);
printf("%d", returnValue);
} while (false);
printf("\n");
return isOk;
}
static bool CallDeleteDevice(DeviceMgtSystem *sys)
{
int deviceId = 0;
bool returnValue = false;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &deviceId) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
returnValue = DeviceMgtSystemDeleteDevice(sys, deviceId);
printf("%s", returnValue ? "true" : "false");
} while (false);
printf("\n");
return isOk;
}
static bool CallQueryDevice(DeviceMgtSystem *sys)
{
int deviceType = 0;
DeviceInfo *returnValue = NULL;
size_t returnSize = 0;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &deviceType) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
returnValue = DeviceMgtSystemQueryDevice(sys, deviceType, &returnSize);
PrintListDeviceInfo(returnValue, returnSize);
} while (false);
FreeListDeviceInfo(returnValue);
returnValue = NULL;
printf("\n");
return isOk;
}
static bool GetCmdName(char* buffer, size_t size)
{
SkipWs();
size_t pos = 0;
char c = (char)getchar();
while (c != '\r' && c != '\n' && c != ' ' && c != '(' && feof(stdin) == 0 && pos < size) {
buffer[pos++] = c;
c = (char)getchar();
}
if (pos >= size) { return false; }
buffer[pos] = '\0';
if (pos == 0) { return feof(stdin) != 0; }
if (feof(stdin) == 0) { (void)ungetc(c, stdin); }
return true;
}
int main(void)
{
char cmd[64] = {0};
bool isOk = GetCmdName(cmd, sizeof(cmd));
DeviceMgtSystem *sys = NULL;
if (strcmp(cmd, "DeviceMgtSystem") != 0) { isOk = false; }
if (isOk) { isOk = CallCreate(&sys); }
while (isOk) {
const char *cmds[] = {"createDevice", "deleteDevice", "queryDevice"};
bool (*funcs[])(DeviceMgtSystem *sys) = {CallCreateDevice, CallDeleteDevice, CallQueryDevice};
if (!GetCmdName(cmd, sizeof(cmd))) {
isOk = false;
break;
}
if (cmd[0] == '\0') {
DeviceMgtSystemFree(sys);
return 0;
}
isOk = false;
for (size_t i = 0; i < sizeof(cmds) / sizeof(cmds[0]); ++i) {
if (strcmp(cmd, cmds[i]) == 0) {
isOk = (*funcs[i])(sys);
break;
}
}
}
printf("Error: Input format incorrect!");
if (sys) { DeviceMgtSystemFree(sys); }
return 0;
}
solution.c文件
#include <stdbool.h>
typedef struct {
int deviceId;
int memSize;
int procId;
} DeviceInfo;
typedef struct {
} DeviceMgtSystem;
// 注意:该函数为类构造函数,返回的对象指针将作为其他待实现函数的入参;框架代码在调用该函数后,会输出 null(而非指针)
static DeviceMgtSystem *DeviceMgtSystemCreate(int procNum, int maxMemSize)
{
return NULL;
}
static int DeviceMgtSystemCreateDevice(DeviceMgtSystem *sys, int deviceId, int deviceType, int memSize)
{
return 0;
}
static bool DeviceMgtSystemDeleteDevice(DeviceMgtSystem *sys, int deviceId)
{
return false;
}
// 注意:返回的数组必须在函数内调用malloc进行内存分配,由框架代码调用free进行内存释放。
// 同时,所返回的数组长度必须保存在 *returnSize 中。
static DeviceInfo *DeviceMgtSystemQueryDevice(DeviceMgtSystem *sys, int deviceType, size_t *returnSize)
{
*returnSize = 0;
return NULL;
}
static void DeviceMgtSystemFree(DeviceMgtSystem *sys)
{
}
总结
未完待续