线程安全队列
两个make线程对val进行++时,val应该定义为全局变量
如果将val定义在各自线程内部,val就是局部变量,对val进行++就是在两个线程各自的栈中进行操作
val定义为全局变量时,需要对该全局变量进行加锁
一定要注意线程的独有空间
信号量
采用数组实现一个线程安全队列,模拟信号量
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <vector>
#define THREAD_NUM 2
class RingQueue
{
private:
std::vector<int> vec_;
size_t capacity_;//队列的容量
//互斥
sem_t lock_;
//同步
sem_t read_;
sem_t write_;
int w_pos_;
int r_pos_;
public:
RingQueue()
:vec_(4)
{
capacity_ = 4;
sem_init(&lock_, 0, 1);
sem_init(&read_, 0, 0);
sem_init(&write_, 0, 4);
w_pos_ = 0;
r_pos_ = 0;
}
~RingQueue()
{
sem_destroy(&lock_);
sem_destroy(&read_);
sem_destroy(&write_);
}
生产者调用
void Push(int data)
{
sem_wait(&write_);
sem_wait(&lock_);
vec_[w_pos_] = data;
w_pos_ = (w_pos_ + 1) % capacity_;
sem_post(&lock_);
sem_post(&read_);
}
消费者调用
void Pop(int* data)
{
sem_wait(&read_);
sem_wait(&lock_);
*data = vec_[r_pos_];
r_pos_ = (r_pos_ + 1) % capacity_;
sem_post(&lock_);
sem_post(&write_);
}
};
void* ReadStart(void* arg)
{
RingQueue* rq = (RingQueue*)arg;
while(1)
{
int data;
rq->Pop(&data);
printf("i am Rd %p, i cum %d\n", pthread_self(), data);
}
return NULL;
}
void* WriteStart(void* arg)
{
RingQueue* rq = (RingQueue*)arg;
int data = 1;
while(1)
{
rq->Push(data++);
sleep(1);
}
return NULL;
}
int main()
{
RingQueue* rq = new RingQueue();
if(rq == NULL)
{
return 0;
}
pthread_t re[THREAD_NUM], wr[THREAD_NUM];
for(int i = 0; i < THREAD_NUM; i++)
{
int ret = pthread_create(&re[i], NULL, ReadStart, (void*)rq);
if(ret < 0)
{
perror("pthread_create");
return 0;
}
ret = pthread_create(&wr[i], NULL, WriteStart, (void*)rq);
if(ret < 0)
{
perror("pthread_create");
return 0;
}
}
for(int i = 0; i < THREAD_NUM; i++)
{
pthread_join(re[i], NULL);
pthread_join(wr[i], NULL);
}
return 0;
}