Linux多线程共享变量的机制涉及多个方面,包括互斥锁、信号量等同步原语的使用,以及线程间通讯的方法,以下是对这些方面的详细解释和示例:
一、互斥锁(Mutex)
1. 定义与作用
定义:互斥锁(Mutex)是一种用于保护临界区的同步机制,确保在同一时刻只有一个线程能够访问共享资源。
作用:防止多个线程同时访问共享资源,从而避免数据竞争和不一致性问题。
2. 使用步骤
1、初始化:在使用前需要对互斥锁进行初始化。
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
2、加锁:在进入临界区前,线程需要获取互斥锁。
pthread_mutex_lock(&mutex);
3、访问共享资源:在持有互斥锁的情况下,线程可以安全地访问共享资源。
4、解锁:完成对共享资源的访问后,线程需要释放互斥锁。
pthread_mutex_unlock(&mutex);
3. 示例代码
#include <stdio.h> #include <stdlib.h> #include <pthread.h> int sharedVar = 0; // 共享变量 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁 void* threadFunc(void* arg) { for (int i = 0; i < 100000; ++i) { pthread_mutex_lock(&mutex); // 加锁 sharedVar++; // 访问共享变量 pthread_mutex_unlock(&mutex); // 解锁 } return NULL; } int main() { pthread_t t1, t2; pthread_create(&t1, NULL, threadFunc, NULL); pthread_create(&t2, NULL, threadFunc, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); printf("Final value of sharedVar: %d ", sharedVar); return 0; }
在这个示例中,两个线程通过互斥锁来同步对共享变量sharedVar
的访问,确保最终结果是准确的。
二、信号量(Semaphore)
1. 定义与作用
定义:信号量是一种更为灵活的同步机制,可以控制多个线程对共享资源的访问,它不仅可以实现互斥访问,还可以实现资源的计数管理。
作用:通过信号量的等待和通知机制,可以实现复杂的线程同步逻辑。
2. 使用步骤
1、初始化:在使用前需要对信号量进行初始化。
sem_t semaphore; sem_init(&semaphore, 0, initialValue);
2、等待(P操作):线程在需要访问共享资源时,执行等待操作,如果信号量的值大于零,则减一并继续执行;否则,线程将阻塞直到信号量的值大于零。
sem_wait(&semaphore);
3、访问共享资源:在持有信号量的情况下,线程可以安全地访问共享资源。
4、释放(V操作):完成对共享资源的访问后,线程需要释放信号量。
sem_post(&semaphore);
5、销毁:在程序结束时,需要销毁信号量。
sem_destroy(&semaphore);
3. 示例代码(生产者-消费者问题)
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define MAXSIZE 5 int buffer[MAXSIZE]; int in = 0; int out = 0; sem_t empty; // 表示空余量的信号量 sem_t full; // 表示满容量的信号量 pthread_mutex_t mutex; // 用于保护临界区的互斥锁 void put(int value) { buffer[in] = value; in = (in + 1) % MAXSIZE; } int get() { int tmp = buffer[out]; out = (out + 1) % MAXSIZE; return tmp; } void* producer(void* arg) { for (int i = 0; i < 10; i++) { sem_wait(&empty); // P操作,检查空余量 pthread_mutex_lock(&mutex); // 加锁保护临界区 put(i); // 生产产品 printf("Produced: %d ", i); pthread_mutex_unlock(&mutex); // 解锁 sem_post(&full); // V操作,增加满容量 sleep(rand() % 5); // 模拟生产时间 } return NULL; } void* consumer(void* arg) { for (int i = 0; i < 10; i++) { sem_wait(&full); // P操作,检查满容量 pthread_mutex_lock(&mutex); // 加锁保护临界区 int tmp = get(); // 消费产品 printf("Consumed: %d ", tmp); pthread_mutex_unlock(&mutex); // 解锁 sem_post(&empty); // V操作,增加空余量 sleep(rand() % 5); // 模拟消费时间 } return NULL; } int main() { pthread_t producerThread, consumerThread; sem_init(&empty, 0, MAXSIZE); // 初始化空余量信号量 sem_init(&full, 0, 0); // 初始化满容量信号量 pthread_mutex_init(&mutex, NULL); // 初始化互斥锁 pthread_create(&producerThread, NULL, producer, NULL); pthread_create(&consumerThread, NULL, consumer, NULL); pthread_join(producerThread, NULL); pthread_join(consumerThread, NULL); sem_destroy(&empty); // 销毁信号量 sem_destroy(&full); // 销毁信号量 pthread_mutex_destroy(&mutex); // 销毁互斥锁 return 0; }
在这个示例中,生产者和消费者通过信号量和互斥锁来实现对缓冲区的同步访问,生产者在生产产品前会检查空余量(empty
),并在生产后增加满容量(full
),消费者在消费产品前会检查满容量(full
),并在消费后增加空余量(empty
),互斥锁用于保护对缓冲区的直接访问,确保在任何时刻只有一个线程能够修改缓冲区的状态。
以上就是关于“linux 多线程共享变量”的问题,朋友们可以点击主页了解更多内容,希望可以够帮助大家!
本文来源于互联网,如若侵权,请联系管理员删除,本文链接:https://www.9969.net/88347.html