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