两个线程同时调用一个函数会出现什么情况?


最近在研究多线程,然后突然想到如果两个线程同时访问一个函数的话,要不要加锁呢,加锁怎么加,不加又怎样这样的问题..然后去网上找了些帖子学习学习......

上面的代码明显执行串了!!!!

函数本身只是代码,代码是只读的,无论多少个线程同时调用都无所谓,因为是只读嘛.但是函数里面总要用到暑假 ,如果数据属性线程级别(比如函数形参-->局部变量-->存在栈上-->每个线程都有自己的栈),那么同时调用是没关系的,因为用的都是本线程的数据;但是如果函数用到一些全局数据,比如全局变量,根据堆内存首地址去访问的堆内存(形参传入的),同时操作一个数据结构(如对一个链表有什么操作),静态局部变量,那就不行了,必须要加锁!!

 

http://blog.youkuaiyun.com/mq_ydn3102/article/details/8546722

1.线程中函数的调用

2.同一个进程中的两个线程调用同一个处理函数

3.两个不同的进程中的两个线程调用同一个处理函数

 

1.线程中函数的调用:

每个进程都会有自己的虚拟地址空间,同一个进程中的每一个线程都会在这个虚拟空间中,并被分配相应的资源. 

线程中的函数实体实在内存中,而函数中的局部变量则会一次被push到栈中.

如果是A函数调用B函数,则会先将A函数的参数和局部变量push到栈中,再将B函数的参数和局部变量push到栈中

具体如下(参数是从右往左压入栈中,__stdcall和__cdecl调用都是这么处理的):

void fun(param1, param2,. param3....paramN)
{
value1;
value2;
...
valueN;
}

如果执行上面的函数在栈中会这样变化

1:将fun函数的传入参数从右到左依次压入到栈中

2:将fun函数的指针压入栈中

3:将ebp,ebx等寄存器入栈保存
4:在栈中依次为各个变量分配空间

执行后的处理:

1.释放变量空间

2.弹出寄存器

3.ret,弹出eip,返回主调方代码

4.释放参数空间

2.两个线程调用同一个函数

 两个线程中的函数的局部变量由于是保存在不同的线程中,因此不需要进行互斥处理(除非有非栈内存在捣乱,这种情况必须要有互斥锁)

3.两个不同进程中的两个线程调用同一个处理函数

同样,两个线程中的函数的局部变量由于是保存在不同的线程中,因此不需要进行互斥处理
 
结论:
因此需要互斥处理的,一般是函数中有全局变量,有动态申请的空间,有静态局部变量,有需要进程数据循环发送(进程传参数给线程)之类的操作需要进行互斥处理

<think>好的,我现在需要回答用户的问题:“C语言怎么同时调用两个函数”。首先,我需要理解用户的需求。用户可能刚接触C语言,想知道如何在一个程序中调用两个不同的函数。可能他们遇到了同时执行两个函数的问题,或者对函数调用的顺序有疑问。 接下来,我要考虑用户的具体情况。他们可能已经知道如何定义一个函数,但不确定如何正确地在主函数调用多个函数。也有可能用户对函数执行顺序或参数传递有疑问。因此,我需要分步骤解释,确保他们能够理解。 首先,我需要回忆C语言中函数调用的基本知识。在C语言中,函数调用是按顺序执行的,也就是说,一个函数执行完后才会执行一个。因此,“同时调用”在严格意义上是不可能的,除非使用多线程,但这对新手来说可能太复杂了。用户可能只是想依次调用两个函数,所以需要明确这一点。 然后,我需要组织回答的结构。首先解释如何定义两个函数,然后在main函数中依次调用它们。给出具体的代码示例,这样用户可以看到实际的语法结构。同时,要提醒用户注意函数声明和定义的顺序,避免编译器报错。 可能用户会混淆“同时调用和顺序调用,因此需要说明两者的区别。如果用户确实需要并发执行,可能需要提到多线程,但要指出这是更高级的内容,可能超出当前问题的范围。 另外,需要检查代码示例是否正确。例如,函数是否需要参数,返回值如何处理。在示例中使用void类型的函数,这样更简单易懂。同时,确保代码中的注释和输出能够帮助用户理解执行顺序。 还要考虑常见的错误,比如忘记声明函数原型,或者在调用函数时使用了错误的语法。因此,在解释中需要提到函数原型的重要性,特别是在函数定义在main函数之后的情况下。 最后,总结关键点,强调调用函数的顺序性,并提供进一步学习的建议,比如如何传递参数或处理返回值,以及提到多线程的概念,让用户知道如果有更复杂的需求可以进一步学习哪些内容。</think>在C语言中,函数调用是按顺序执行的,无法真正“同时执行两个函数(除非使用多线程)。但可以通过以下步骤依次调用两个函数: --- ### 步骤说明 1. **定义两个函数** 先编写两个独立的功能函数,例如: ```c void func1() { printf("这是函数1\n"); } void func2() { printf("这是函数2\n"); } ``` 2. **声明函数原型(可选)** 如果函数定义在`main()`之后,需要在文件顶部声明: ```c void func1(); // 函数原型声明 void func2(); ``` 3. **在main()中依次调用** 按需求顺序调用两个函数: ```c int main() { func1(); // 先调用func1 func2(); // 再调用func2 return 0; } ``` --- ### 完整代码示例 ```c #include <stdio.h> // 声明函数原型 void func1(); void func2(); int main() { func1(); // 调用一个函数 func2(); // 调用第二个函数 return 0; } // 函数定义 void func1() { printf("函数1执行\n"); } void func2() { printf("函数2执行\n"); } ``` --- ### 输出结果 ``` 函数1执行 函数2执行 ``` --- ### 关键点 1. **顺序执行**:C语言默认是单线程的,函数调用顺序依次执行。 2. **函数原型**:如果函数定义在`main()`之后,必须提前声明。 3. **参数与返回值**:若函数需要参数或返回值,调用时需正确处理,例如: ```c int add(int a, int b) { return a + b; } int result = add(3, 5); // 调用带参数的函数 ``` --- ### 进阶扩展 如果需要“同时执行(并发),需学习: - **多线程**:使用`pthread`库(Linux)或`<thread>`(C11标准)。 - **异步编程**:通过回调函数或事件驱动实现逻辑并行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值