8.3.5 原子操作
在同一時刻只有唯一的線程對這個資源進行訪問。這有點類似互斥對象對共享資源的訪問的保護,但是原子操作更加接近底層,因而效率更高。
(1)pthread
#include <stdatomic.h>
atomic_int atomicVariable;
atomic_init(&atomicVariable, 0);int value = atomic_load(&atomicVariable);// 原子加載原子變量的值
atomic_store(&atomicVariable, value);// 儲存原子變量
int oldValue = atomic_fetch_add(&atomicVariable, value);//原子加法操作
oldValue = atomic_fetch_sub(&atomicVariable, value);//原子減法
示例代碼:
#include <stdio.h>
#include <stdlib.h>
#include <stdatomic.h>
#include <pthread.h>#define NUM_THREADS 4
#define ITERATIONS 1000000// 全局原子變量
atomic_int sharedVariable = 0;// 線程函數,每個線程對共享變量進行一百萬次的加法操作
void* threadFunc(void* arg) {for (int i = 0; i < ITERATIONS; ++i) {atomic_fetch_add(&sharedVariable, 1);}return NULL;
}int main() {pthread_t threads[NUM_THREADS];// 創建多個線程for (int i = 0; i < NUM_THREADS; ++i) {if (pthread_create(&threads[i], NULL, threadFunc, NULL) != 0) {fprintf(stderr, "Error creating thread\n");exit(EXIT_FAILURE);}}// 等待線程執行完畢for (int i = 0; i < NUM_THREADS; ++i) {if (pthread_join(threads[i], NULL) != 0) {fprintf(stderr, "Error joining thread\n");exit(EXIT_FAILURE);}}// 輸出最終的共享變量值printf("Final value of sharedVariable: %d\n", atomic_load(&sharedVariable));return 0;
}
(2)std::atomic
使用步驟:
#include <atomic>
std::atomic<int> total(0); // 初始化
int value = total.load(); // 加載
total.store(42); //原子儲存
int result = total.fetch_add(5); //加法
示例代碼:
#include <iostream>
#include <thread>
#include <atomic>
#include <time.h>
#include <mutex>
#include <atomic>#define MAX 100000
#define THREAD_COUNT 20// 原子操作
std::atomic_int total(0);void threadTask()
{for (int i = 0; i < MAX; i++){total += 1;total -= 1;}
}int main()
{clock_t start = clock();std::thread t[THREAD_COUNT];for (int i = 0; i < THREAD_COUNT; ++i){t[i] = std::thread(threadTask);}for (int i = 0; i < THREAD_COUNT; ++i){t[i].join();}clock_t finish = clock();std::cout << "result:" << total << std::endl; // 計算結果std::cout << "duration:" << finish - start << "ms" << std::endl; // 計算耗時return 0;
}