线程同步的方式

一、线程同步的概念

线程同步是多线程编程中的一个重要概念。在多线程环境中,多个线程同时访问共享数据时,容易造成数据的不一致性和错误。因此,需要对多个线程进行协调与管理,保证它们之间的执行次序、执行结果的可预测性和一致性。

二、多线程4钟同步方式

常见的线程同步方式有4种,分别是:

  • 互斥锁:采用互斥方式对共享资源进行访问控制。
  • 条件变量:多个线程通过条件变量进行通信和唤醒。
  • 自旋锁:在等待锁的过程中,不放弃CPU时间,而是进行一定时间的忙等待。
  • 信号量:用于控制资源的访问次数,类似于对某个共享变量的计数器。

三、线程同步的方式有哪些

除了上述提到的常见线程同步方式,还有以下几种线程同步方式:

  • 读写锁:在对共享资源进行读操作时可以多个线程同时访问,而在对共享资源进行写操作时只有一个线程可以访问。
  • 屏障(barrier):用于同步多个线程的执行,使它们在某个点汇合并行执行。
  • 原子操作:对共享资源进行操作时,保证操作的原子性,即操作不可中断。
  • 同步队列:实现多个线程间的消息传递,线程在同步队列中等待消息的到来。

四、加锁线程是线程同步的方式吗

加锁是线程同步的一种实现方式,即通过加锁控制多个线程访问共享数据的先后顺序,从而实现对数据访问的同步。在加锁期间,只有获得锁的线程才能访问共享资源,其他线程需要等待。

五、线程同步和异步

线程同步和异步都是多线程编程中的重要概念。线程同步指多个线程之间的执行顺序是固定的,任何一个线程都无法独立完成任务。而异步则指多个线程之间的执行顺序是不确定的,可以独立完成任务。

六、线程同步的四种方式

再次总结一下线程同步的四种方式:

  • 互斥锁
  • 条件变量
  • 自旋锁
  • 信号量

七、实现线程同步的方法

实现线程同步的方法有很多,下面介绍几种比较常用的实现方式:

1、使用互斥锁进行线程同步

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

pthread_mutex_t mutex;

void *threadFunction(void *arg) {
  pthread_mutex_lock(&mutex);
  printf("Hello from thread %d\n", *(int*)arg);
  pthread_mutex_unlock(&mutex);
  return NULL;
}

int main() {
  pthread_t tid[5];
  int i, args[5];
  pthread_mutex_init(&mutex, NULL);
  for (i = 0; i < 5; i++) {
    args[i] = i;
    pthread_create(&tid[i], NULL, threadFunction, &args[i]);
  }
  for (i = 0; i < 5; i++) {
    pthread_join(tid[i], NULL);
  }
  pthread_mutex_destroy(&mutex);
  return 0;
}

2、使用条件变量进行线程同步

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

pthread_mutex_t mutex;
pthread_cond_t condVar;

int count = 0;

void *producer(void *arg) {
  int i;
  for (i = 0; i < 5; i++) {
    pthread_mutex_lock(&mutex);
    count++;
    printf("producer: produced %d\n", count);
    pthread_mutex_unlock(&mutex);
    pthread_cond_signal(&condVar);
  }
  return NULL;
}

void *consumer(void *arg) {
  int i;
  for (i = 0; i < 5; i++) {
    pthread_mutex_lock(&mutex);
    while (count == 0) {
      pthread_cond_wait(&condVar, &mutex);
    }
    count--;
    printf("consumer: consumed %d\n", count);
    pthread_mutex_unlock(&mutex);
  }
  return NULL;
}

int main() {
  pthread_t tid[2];
  pthread_mutex_init(&mutex, NULL);
  pthread_cond_init(&condVar, NULL);
  pthread_create(&tid[0], NULL, producer, NULL);
  pthread_create(&tid[1], NULL, consumer, NULL);
  pthread_join(tid[0], NULL);
  pthread_join(tid[1], NULL);
  pthread_mutex_destroy(&mutex);
  pthread_cond_destroy(&condVar);
  return 0;
}

3、使用原子变量进行线程同步

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

_Atomic int count = 0;

void *threadFunction(void *arg) {
  int i, n = *(int*)arg;
  for (i = 0; i < 5; i++) {
    atomic_fetch_add(&count, n);
    printf("thread %d: count = %d\n", n, count);
  }
  return NULL;
}

int main() {
  pthread_t tid[2];
  int args[] = {1, -1};
  pthread_create(&tid[0], NULL, threadFunction, &args[0]);
  pthread_create(&tid[1], NULL, threadFunction, &args[1]);
  pthread_join(tid[0], NULL);
  pthread_join(tid[1], NULL);
  return 0;
}

4、使用屏障进行线程同步

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

#define NUM_THREADS 5

pthread_barrier_t barrier;

void *threadFunction(void *arg) {
  int n = *(int*)arg;
  printf("thread %d: before barrier\n", n);
  pthread_barrier_wait(&barrier);
  printf("thread %d: after barrier\n", n);
  return NULL;
}

int main() {
  pthread_t tid[NUM_THREADS];
  int i;
  pthread_barrier_init(&barrier, NULL, NUM_THREADS);
  for (i = 0; i < NUM_THREADS; i++) {
    int *arg = malloc(sizeof(*arg));
    *arg = i;
    pthread_create(&tid[i], NULL, threadFunction, arg);
  }
  for (i = 0; i < NUM_THREADS; i++) {
    pthread_join(tid[i], NULL);
  }
  pthread_barrier_destroy(&barrier);
  return 0;
}

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/312711.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2025-01-06 09:47
下一篇 2025-01-06 15:17

相关推荐

  • Python缓存图片的处理方式

    本文将从多个方面详细阐述Python缓存图片的处理方式,包括缓存原理、缓存框架、缓存策略、缓存更新和缓存清除等方面。 一、缓存原理 缓存是一种提高应用程序性能的技术,在网络应用中流…

    编程 2025-04-29
  • Python线程等待指南

    本文将从多个方面详细讲解Python线程等待的相关知识。 一、等待线程结束 在多线程编程中,经常需要等待线程执行完毕再进行下一步操作。可以使用join()方法实现等待线程执行完毕再…

    编程 2025-04-29
  • Python两个线程交替打印1到100

    这篇文章的主题是关于Python多线程的应用。我们将会通过实际的代码,学习如何使用Python两个线程交替打印1到100。 一、创建线程 在Python中,我们可以使用Thread…

    编程 2025-04-28
  • ROS线程发布消息异常解决方法

    针对ROS线程发布消息异常问题,我们可以从以下几个方面进行分析和解决。 一、检查ROS代码是否正确 首先,我们需要检查ROS代码是否正确。可能会出现的问题包括: 是否正确初始化RO…

    编程 2025-04-28
  • Python在线编辑器的优势与实现方式

    Python在线编辑器是Python语言爱好者的重要工具之一,它可以让用户方便快捷的在线编码、调试和分享代码,无需在本地安装Python环境。本文将从多个方面对Python在线编辑…

    编程 2025-04-28
  • Java表单提交方式

    Java表单提交有两种方式,分别是get和post。下面我们将从以下几个方面详细阐述这两种方式。 一、get方式 1、什么是get方式 在get方式下,表单的数据会以查询字符串的形…

    编程 2025-04-27
  • Python线程池并发爬虫

    Python线程池并发爬虫是实现多线程爬取数据的常用技术之一,可以在一定程度上提高爬取效率和数据处理能力。本文将从多个方面对Python线程池并发爬虫做详细的阐述,包括线程池的实现…

    编程 2025-04-27
  • 用Pythonic的方式编写高效代码

    Pythonic是一种编程哲学,它强调Python编程风格的简单、清晰、优雅和明确。Python应该描述为一种语言而不是一种编程语言。Pythonic的编程方式不仅可以使我们在编码…

    编程 2025-04-27
  • Java多版本支持实现方式

    本文将从以下几个方面阐述如何实现Java多版本支持,并给出可行的代码示例。 一、多版本Java环境概述 Java是一门跨平台的编程语言,但是在不同的应用场景下,可能需要使用不同版本…

    编程 2025-04-27
  • SpringBoot Get方式请求传参用法介绍

    本文将从以下多个方面对SpringBoot Get方式请求传参做详细的阐述,包括URL传参、路径传参、请求头传参、请求体传参等,帮助读者更加深入地了解Get请求方式下传参的相关知识…

    编程 2025-04-27

发表回复

登录后才能评论