为什么两次调用同一函数, 输入相同, 输出却不同呢? (解决困扰自己好几天的问题, 还是有点激动哈, 奖励自己一顿丰厚的晚餐)

972 篇文章 329 订阅
24 篇文章 11 订阅

        注意:下面的文件都是.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中的结果。 原因是, 它们是两个不同的进程, 从进程号便可以看出。

 

      在这个问题上确实纠结良久, 找到原因并解决了它, 内心还是有点激动哈, 亦有不少收获。晚上奖励了自己一顿大餐。


 


 

 

      

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值