本文共 3001 字,大约阅读时间需要 10 分钟。
使用VC2010或以上版本编写一个多线程注册验证程序,要求:
以下程序基于VS2019设计,VS2010可能无法运行。
首先新建一个MFC应用
应用程序类型选择基于对话框,点击完成
在资源视图打开以下界面,开始制作GUI界面
从工具箱中添加控件,本项目主要用到三个控件,按钮Button、可编辑文本框Edit Control、静态文本框Static Text
制作好的GUI如下(界面有点简陋,求轻喷):
完成GUI制作后,我们就可以往StudengsManageSystemDlg.cpp中添加代码了。根据题目的要求,我们需要保存学生的学号和姓名,因此我们创建一个包含学号、姓名以及一个构造函数的学生类,为了方便之后的查询对比,将学号用long long型数据保存。
// 创建一个学生类class Student{public: long long SID; CString Name; Student(long long sid, CString name) { SID = sid; Name = name; }};
接下来我们需要一个列表来保存每个学生类的实例
// 新建一个学生列表vectorstulist;
然后在GUI设计界面双击保存
按钮,跳转到这个保存
按钮的回调函数
void CStudentsManageSystemDlg::OnBnClickedButton1(){ CString sid; CString name; // 将文本框1的内容输出到sid GetDlgItem(IDC_EDIT3)->GetWindowText(sid); // 将文本框2的内容输出到name GetDlgItem(IDC_EDIT4)->GetWindowText(name); // 判断待保存的学号和姓名中是否有空值 if (name == "" || sid == "") { CString str_prompt = CString("提示框"); CString str = CString("学号/姓名不能为空!"); MessageBox(str, str_prompt, MB_OK); return; } // 学号必须为数字,如果存在非数字则返回,并弹出提示框 for (int i = 0; i < sid.GetLength(); i++) { if (sid[i] < '0' || sid[i] > '9') { CString str_prompt = CString("提示框"); CString str = CString("请输入正确的学号!"); MessageBox(str, str_prompt, MB_OK); return; } } // 将上述内容存到学生列表中 stulist.push_back(Student(_ttoll(sid), name));}
由于题目要求使用多线程的方式来验证是否注册,所以需要编写一个查询函数search_task(long long sid)
,它的形参是待查询的学号。
void search_task(long long sid){ if (stulist.size() == 0) { CString str_prompt = CString("提示框"); CString str = CString("学生列表为空!"); MessageBox(NULL, str, str_prompt, MB_OK); return; } for (int i = 0; i < stulist.size(); i++) { if (stulist[i].SID == sid) { CString str_prompt = CString("提示框"); MessageBox(NULL, CString("姓名为:") + stulist[i].Name, str_prompt, MB_OK); break; } else { if (i == stulist.size() - 1) { CString str_prompt = CString("提示框"); CString str = CString("未注册!"); MessageBox(NULL, str, str_prompt, MB_OK); } } }}
最后向查询
按钮中添加回调函数
void CStudentsManageSystemDlg::OnBnClickedButton2(){ CString sid; GetDlgItem(IDC_EDIT5)->GetWindowText(sid); // 待查询的学号不能为空 if (sid == "") { CString str_prompt = CString("提示框"); CString str = CString("查询学号不能为空!"); MessageBox(str, str_prompt, MB_OK); return; } for (int i = 0; i < sid.GetLength(); i++) { if (sid[i] < '0' || sid[i] > '9') { CString str_prompt = CString("提示框"); CString str = CString("请输入正确的学号!"); MessageBox(str, str_prompt, MB_OK); return; } } long long SID = _ttoll(sid); // 开启查询线程 thread t(search_task, SID); // 必须将线程join或者detach,子线程结束后主进程才可以退出 t.detach();}
完成上述操作后,就可以测试程序了。
2017000000001 王小明
2017000000002 王大明
,并查询2017000000001
以及2017000000003
,得到以下结果。2017xxxxxxxx1
,弹出提示框,结果正确。测试程序时,可能没有体现出多线程的作用,因为输入的样本数较少,执行查询任务时也就一瞬间的事。但是样本数量比较大时,查询任务将会耗费比较多的时间,如果将查询任务放在回调函数中执行,将会导致在查询过程中,系统无法响应,表现为系统卡住。
当然当样本数较大时,还可能发生前一次查询还没结束,另一次查询就发起了的情况,这时候两次查询都需要用到学生列表,所以
由于时间限制,并没有将学生列表中的数据保存到一个本地文件中,所以本程序中所有输入的数据都保存在一个动态列表中,当程序关闭时,这些数据将会丢失。
完整项目在这里(其实按照上述步骤操作应该能得到一个差不多的程序):
转载地址:http://mlvgn.baihongyu.com/