C++ n个线程循环执行三次
今天做了CVTE的笔试题,最后一道编程题是这样的:
有n个线程,第一个线程输出’A’,第二个线程输出’B’,第三个线程输出’C’……以此类推~~~
现输入n,要求循环顺序执行前n个线程三次,不允许使用sleep
例如:
input:3
output:
ABCABCABC
input:
6
output:
ABCDEFABCDEFABCDEF
由于我对C++的理解基本处于 C + STL阶段 (STL还不一定都会用),多线程方面就很炸了,关键是这玩意儿笔试写代码不仅不让在本地IDE里调试,它给的笔试网站上还不能调试,交了就是交了,没有评测,啥都没有(这是真笔试呀。。和让你写卷子的区别大概就是这玩意儿是用键盘~~~)
吐槽结束,虽然笔试尽是写bug了,但自己写的bug,跪着也得改完~~
这是调出来的代码:
#include<iostream>
#include<thread>
using namespace std;
int flag = 0, n;
class Test
{
private:
static char cnt;
char a;
public:
void operator()()
{
a = cnt ++;
while(flag < 3*n)
{
if(flag % n == a - 'A')
{
cout << a;
flag ++;
}
}
}
};
char Test::cnt = 'A';
int main()
{
cin >> n;
thread wait([] {
while (flag < n*3);
});
for(int i = 0; i < n; ++ i)
{
thread th{Test()};
th.detach();
}
wait.join();
return 0;
}
简单解释一下吧:
-
如何启动n个线程:不可能手动一个一个地去建线程,所以使用可调用类型来初始化线程,然后用个for循环建n个对象即可。
-
如何保证线程的顺序执行:首先,每建一个线程,就给它detach出来,让它自己去执行,不影响我继续建线程。然后就是用一个全局变量flag作为标志符,每个线程能够执行输出语句的flag都不一样,每执行一次输出则flag++,让下一个线程来执行输出。
-
如何保证输出结束前主线程不会结束:启动一个wait线程来强制等到flag一直加到3*n才结束,这时wait当然得用join了,阻塞住主线程,不让它结束~~~
最后记一下自己笔试时写的傻逼代码:
#include<iostream>
#include<thread>
using namespace std;
int flag = 0;
class Test
{
private:
static char cnt = 'A';
char a;
public:
Test(){ a = cnt ++;}
void func(int n)
{
while(flag < 3*n)
{
if(flag % n == a - 'A')
{
cout << a;
flag ++;
}
}
}
}a[32];
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; ++ i)
{
thread th{a[i].func(n)};
th.detach();
}
return 0;
}
不能调试就啥都不会的我还是记一下这里面明显的几个bug吧:
- static char cnt = ‘A’; 典型Java用多了的后遗症。。。Java语法这样倒是没问题,C++的话,我只能说自己写的是傻逼代码了。。。C++里,类的一般属性的初始化都是在构造函数里面进行的,然而static属性不一样,构造函数是用于构造对象的,而static属性不属于对象,所以它不能在构造函数里初始化。既然不能在构造函数里初始化,又不能直接在声明时初始化,就只能在类外面再定义一次喽:char Test::cnt = ‘A’;
- thread th{a[i].func(n)}; 我都不知道自己写的什么妖怪,使用a[i].func(n)做参数传入的不是个函数,而是它的返回值~~~所以我后来就直接重载了操作符()
- 比起上面两个,没有wait线程就不算什么了,毕竟我的多线程水平基本都跟刚接触C++的差不多~~~