線程同步的方式

一、線程同步的概念

線程同步是多線程編程中的一個重要概念。在多線程環境中,多個線程同時訪問共享數據時,容易造成數據的不一致性和錯誤。因此,需要對多個線程進行協調與管理,保證它們之間的執行次序、執行結果的可預測性和一致性。

二、多線程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/zh-hant/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

發表回復

登錄後才能評論