注意:下面的文件都是.cpp文件或者.h文件, 没有.c文件。
先来看看有static情况
#include <stdio.h>
int fun()
{
	static int i = 0;
	i++;
	return i;
}
int main()
{
	int a = -1;
	int b = -1;
	a = fun();
	printf("%d\n", a);
	b = fun();
	printf("%d\n", b);
	return 0;
}这个很简单, 两次调用fun, 得到的a和b是不一样的。
再看看看全局变量:
#include <stdio.h>
int g_n = -1;
int fun()
{
	return g_n;
}
int main()
{
	int a = -1;
	int b = -1;
	// 程序猿A在这里调用fun
	a = fun();
	printf("%d\n", a);
    //程序猿C在这里写了一些复杂的代码
	g_n = 100;
	// 程序猿B在这里调用fun
	b = fun();
	printf("%d\n", b);
	return 0;
}这个也好理解, 全局变量嘛, 万恶之源。
再来看个:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int fun()
{
	return rand();
}
int main()
{
	int a = -1;
	int b = -1;
	a = fun();
	printf("%d\n", a);
	b = fun();
	printf("%d\n", b);
	return 0;
}a和b的值不一样, 这种也很好理解。
类似这样的地方太多了, 都是不可重入的函数。
下面看看这个案例吧: 在某复杂系统中, 从某一时刻起, 比如说是set事件发生后, 模块A每次调用函数a, 都得到结果x, 模块B每次调用函数b, 都得到结果y. (x和y不相同)
简化一下原来的模型:
#include <stdio.h>
int g_n = 1;
void set()
{
	g_n = 100;
}
int fun()
{
	return g_n;
}
int main()
{
	int a = -1;
	int b = -1;
	// A 模块
	set();      // set事件发生后
	a = fun();
	printf("%d\n", a);
	// B 模块
	b = fun();
	printf("%d\n", b);
	return 0;
}
运行一下, 结果a, b都是100啊, 看来我模拟错了。
由于系统比较复杂, 相关进程比较多, 而且杂乱。 我当时看到A和B同时调用fun, 就误以为它们三者在同一个进程中, 是一个三口之家。 问了几个同事, 也没有想到是不同进程加载动态链接库fun造成的。我当时也没有意识到A模块和B模块属于不同的进程, 没有意识到fun函数是以动态链接库的形式存在的。
下面, 继续看:
动态库程序:
#include <stdio.h>
#include <windows.h>
int g_n = 1;
_declspec(dllexport) void set()
{
	g_n = 100;
}
_declspec(dllexport) int fun()
{
	printf("current pid is %ld\n", GetCurrentProcessId());
	return g_n;
}
模块A: 设对应的.exe为tes1.exe
#include <stdio.h>
#include "myTest.h"
#pragma comment(lib, "Test.lib")
int main()
{
	int a = -1;
	printf("%d\n", fun());
	set(); // 在某种情况下, 发生了set事件
	
	while(1)
	{
		printf("%d\n", fun());
		getchar();
	}
	return 0;
}
        模块B:设对应的.exe为tes2.exe
#include <stdio.h>
#include "myTest.h"
#pragma comment(lib, "Test.lib")
int main()
{
	int a = -1;
	printf("%d\n", fun());
	
	while(1)
	{
		printf("%d\n", fun());
		getchar();
	}
	return 0;
}
        现在, 在同一PC上, 同时运行test1.exe和test2.exe, 得到结果:
我们看到, 上述的set事件并没有改变B中的结果。 原因是, 它们是两个不同的进程, 从进程号便可以看出。
在这个问题上确实纠结良久, 找到原因并解决了它, 内心还是有点激动哈, 亦有不少收获。晚上奖励了自己一顿大餐。