线程同步(互斥锁、条件变量、读写锁、自旋锁)

线程同步是多线程编程中确保共享数据一致性的重要手段。互斥锁能确保同一时间只有一个线程访问数据,条件变量允许线程等待特定条件发生,自旋锁适用于锁持有时间短的情况,而读写锁则在读操作频繁时提高效率。通过这些机制,可以避免并发访问导致的数据错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程同步

所谓线程同步,就是有多个线程共享相同的内存时,需要确保共享数据在每个线程中都是一致的。若同一个共享变量在两个及以上线程中所显示的结果是不一样的,就表明线程不同步。

什么情况下需要使用线程同步?
当一个线程可以修改的变量,其它线程也可以读取或修改的时候,必须进行线程同步,否则可能导致错误。

假设有两个线程A和B,需要对整型全局变量i进行递增操作,过程如下所示:

递增操作不是原子操作,编译器完成递增操作实际上需要3条机器指令:
(1)将变量从内存单元读入寄存器;
(2)在寄存器中对变量进行增量操作;
(3)把寄存器中新的值写回到内存单元。

两个线程在进行递增操作时,有可能出现如下图所示情况,
在这里插入图片描述
1、线程A运行,把变量i的值(5)读入到线程A的寄存器中;
2、线程A的寄存器内容进行增量操作,寄存器的值变为6;与此同时,线程B运行,将变量i的值读入到线程B的寄存器中,由于线程A的寄存器的值还未写回内存单元,因此读入到线程B的寄存器的值仍为5。
3、将线程A寄存器的值写回内存单元,变量i的值变为6;与此同时,线程B的寄存器内容进行增量操作,其寄存器的值变为6;
4、将线程B寄存器的值写回内存单元,变量i的值变为6;

从上述步骤可以看出,经过两次递增操作之后,变量i的值并没有从5变为7,而是从5变为6,产生了错误的结果。写两个线程递增一个全局变量的情境验证,如下:

#include<stdio.h>
#include<pthread.h>

#defeine NUMLOOP 20

int i=0;

void* threadFunc(void* vptr)
{
   
  int k;
  for (k=0;k<NUMLOOP;k++)
  {
   
    ++i;
    printf("B %ld:%d\n",pthread_self(),i);
  }
}

int main()
{
   
  pthread_t tidB;
  pthread_create(&tidB,NULL,&threadFunc,NULL):  //创建子线程B

  //假设主线程为线程A
  for (int k=0;k<NUMLOOP;k++)
  {
   
    ++i;
    printf("A %ld:%d\n",pthread_self(),i);
  }

  pthread_join(tidB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值