线程同步小练——线程互斥锁

来源:互联网 发布:sae网络的边界网关 编辑:程序博客网 时间:2024/06/18 04:47
很久没有写应用层的程序了,今天帮同学的忙。写了一个关于生产者与消费者的问题。具体的需求如下:

用Posix接口实现一个可以运行的变种生产者消费者问题:
生产者可以无限生产,无需关心消费者是否取走
消费者只能消费生产者生产出来的商品
注意回绕问题,提出解决方案
附上源代码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>


#define BUFF_SIZE 20

sem_t full;/* keep track of the number of full spots */
sem_t empty;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

int value[BUFF_SIZE] = { 0 };
int item_c = 0;
int item_p = 0;


void *Producer(void *arg)
{
while (1) {

pthread_mutex_lock(&mutex1);

printf("Producer run\n");
value[item_p % BUFF_SIZE] = item_p * 2 % BUFF_SIZE;
item_p++;
if (item_p > BUFF_SIZE) {
item_p = 0;
}
//p < c, 消费者还没有消费,生产者休眠。
if (item_p == item_c) { //如果出现了生产者回绕过多的生产,则等待消费者消费了然后方可生产,现在睡眠生产者
sem_post(&full);//唤醒已经生产的信号量
sem_wait(&empty);//因为没有空位用来生产,所以睡眠他
} else {
sem_post(&full);//唤醒已经生产的信号量
}
pthread_mutex_unlock(&mutex1);

sleep(1);
}

}

void *Consumer(void *arg)
{
int myv = 0;
while (1) {
//p < c
if (item_c == item_p) {//如果出现消费者消费的数额直逼生产者已经生产的最后一个的时候,将消费者唤醒。
sem_post(&empty);//已经有空位,唤醒生产
sem_wait(&full);//等待生产结束
}

pthread_mutex_lock(&mutex1);
myv = value[item_c % BUFF_SIZE];
printf("Consumer run, %d\n", myv);
item_c++;
if (item_c > BUFF_SIZE) {
item_c = 0;
}
pthread_mutex_unlock(&mutex1);

//p > c , c追上了p,生产者没有生产的了,消费者需要休眠,同时唤醒生产者生产
if (item_c == item_p) {//如果出现了回绕问题,消费者需要等待生产者产生
sem_post(&empty);
sem_wait(&full);
}

sleep(4);
}
}

int main()
{
pthread_t idP, idC;


sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFF_SIZE);


pthread_create(&idP, NULL, Producer, (void *) 0);
pthread_create(&idP, NULL, Consumer, (void *) 0);

pthread_exit(NULL);
}

总结一下:
其中还是遇到了一些问题,还是看出来自己在应用层的功力尚浅啊。需要努力。
其一——线程同步的问题:
目地:确保不同的线程访问共享的存储内容的时候不会访问到无效的数值。这个时候就需要对线程进行同步。
具体的方式:
第一步:定义一个全局的互斥量pthread_mutex_t mutex_1 = PTHREAD_MUTEX_INITIALIZER;(也可以动态定义pthread_mutex_init(mutex_1, NULL);
第二步:加锁或者解锁:
pthread_mutex_lock(&mutex_p);
pthread_mutex_unlock(&mutex_p);
其二——多个锁的时候,为了防止死锁。
如果多个锁,是没有相互关系的,那么在加锁之前应该处于前一个锁解锁之后,不然会出现死锁。
原创粉丝点击