#define、#ifdef、#endif用法:
#define可以用来定义一个预处理宏,单独使用的话一般是用于宏替换,即将宏名替换为变量、常数、表达式等。
#define hong 7;
#define f(x, y) x+y;
#define zifuchuan "abc";
int main() {
int a = hong;
cout << a << endl; //输出7
int b = 2;
int he = f(a, b)
cout << he << endl; //输出9(即7+2)
string c = zifuchuan;
cout << c << endl; //输出abc
return 0;
}
#define 也可以与#undef、#ifdef、#else、#ifndef、#endif连用,这时#define一般只是为了定义一个预处理宏,而不是为了宏替换。#undef可以消去所定义的宏,#ifdef和#ifndef是条件编译的开始,即是否定义了宏(同if);#else同else,可不写;#endif是条件编译的结束。
#define hong 7; //定义了hong这个宏,并替换为7
#undef hong //删除定义的hong这个宏
#define qita
int main() {
#ifdef qita
cout << "定义了qita这个宏" << endl;
#else
cout << "没有定义qita这个宏" << endl;
#endif
#ifndef hong
cout << "没有定义hong这个宏" << endl;
#else
cout << "定义了hong这个宏" << endl;
#endif
return 0;
}
注:由于进、出windows临界区的效果与mutex(互斥锁)的加锁、解锁相同,故下面用加锁代替进入windows临界区,解锁代替从windows临界区中出来。
windows临界区位于头文件<windows.h>中,记得加.h。其实用处和mutex差不多,都可以给数据加锁,解锁。有一点不同的是,mutex只能同时加一次锁,但windows临界区可以多次进入,当然了,每进入一次就要有一次出去,如果出去次数少了(相当于只有加锁没有解锁),就会一直呆在临界区里,堵塞住其他线程。
#include<iostream>
#include<thread>
#include<string>
using namespace std;
#include<windows.h>
#define _Wind_
class A {
private:
#ifdef _Wind_
CRITICAL_SECTION my_ljq; //定义一个windows临界区
#endif
public:
//函数1
void hanshu1() {
for (int i = 0; i < 3; i++) {
#ifdef _Wind_
EnterCriticalSection(&my_ljq); //进入临界区(加锁)
EnterCriticalSection(&my_ljq);
cout << "调用函数1, id = " << this_thread::get_id() << endl;
LeaveCriticalSection(&my_ljq); //离开临界区(解锁)
LeaveCriticalSection(&my_ljq);
#endif
}
}
//函数2
void hanshu2() {
for (int i = 0; i < 10; i++) {
#ifdef _Wind_
EnterCriticalSection(&my_ljq); //进入临界区(加锁)
cout << "调用函数2, id = " << this_thread::get_id() << endl;
LeaveCriticalSection(&my_ljq); //离开临界区(解锁)
#endif
}
}
};
int main() {
A a;
thread thread1(&A::hanshu1, &a);
thread thread2(&A::hanshu2, &a);
thread1.join();
thread2.join();
return 0;
}
若想防止忘记解锁的情况发生,可以自定义一个RAII(Resource Acquire Is Initial)类,也就是资源获取即初始化类。该类在这的的特点为:在调用构造函数时进入windows临界区,在调用析构函数时出windows临界区。类定义如下:
class Win_Lock {
private:
CRITICAL_SECTION* Lock_;
public:
Win_Lock(CRITICAL_SECTION* Lock1) { //获取已经初始化完成的windows临界区
Lock_ = Lock1;
EnterCriticalSection(Lock_); //加锁
}
~Win_Lock() {
LeaveCriticalSection(Lock_); //在结束时调用析构函数自动解锁
}
};