多线程,同步,互斥(生产者/消费者)

版权声明:请在征得作者同意的情况下,可以进行非盈利性引用。引用请注明出处:“作者:慕华思弦 转载地址” 字样,以尊重作者的劳动成果,并保持良好的版权意识。 https://blog.csdn.net/Superman___007/article/details/82861413

数据污读:bool 的 true   和   bool 的 false , 当1线程执行true时读文件, 为false时2线程读文件,但是由于线程的cpu分时复用,可能还会执行 true 操作 , 导致读入数据异常 .                                                                                                                                                    线程之间数据共享:
        污读:
        A--(读)-->data
        B--(写)-->data
        污写:                                                                                                                                                                                                A--(true)  bool   flag                                                                                                                                                                            B--(false) bool   flag
        解决方法:原子性 : 就是在执行读操作的时候需要把读操作执行完毕 , 执行写操作的时候需要把写操作执行完毕 .

互斥:指两个或两个以上的任务,每次只能有一个任务访问某资源。
    其他任务必须等待。
    reader:
        lock l;
        read
        unlock l;
    author:
        lock  l;
        write;
        unlock l;

   上锁实现互斥的操作 :

#include<stdio.h>
#include<pthread.h>
//两个线程:一个读,一个写
int lock_var;
//定义互斥量
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
//互斥:读者读时,写者不能写,反之一样.
//同步:先写,再读(按照顺序)
void* reader(void* arg)//读者
{
	char* pb=(char*)arg;
	while(1)
	{
		//上锁
		pthread_mutex_lock(&mutex);
		//读取
		printf("读取的内容为:%s\n",pb);
		//解锁
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
}
void* author(void* arg)//写者
{
	char* pb=(char*)arg;
	while(1)
	{
		//上锁
		pthread_mutex_lock(&mutex);
		//写入
		printf("请输入内容:\n");
		scanf("%s",pb);
		printf("写入完成\n");
		//解锁
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
}
//读写者问题:
int main()
{
//共同缓冲区
	char buf[100]="";
//创建两个线程
	pthread_t rtid,wtid;
	pthread_create(&rtid,NULL,reader,buf);	
	pthread_create(&wtid,NULL,author,buf);
//等待子线程结束
	pthread_join(rtid,NULL);
	pthread_join(wtid,NULL);

//销毁锁
	pthread_mutex_destroy(&mutex);
	return 0;
}

   通过信号量来实现互斥 :

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
sem_t m1,m2;
//两个线程:一个读,一个写
//互斥:读者读时,写者不能写,反之一样.
//同步:先写,再读(按照顺序)
void* reader(void* arg)//读者
{
	while(1)
	{
		sem_wait(&m1);
		printf("我是---A线程\n");
		sleep(1);
		sem_post(&m2);
	}
}
void* author(void* arg)//写者
{
	while(1)
	{
		sem_wait(&m2);
		printf("我是---B线程\n");
		sleep(1);
		sem_post(&m1);
	}
}
//读写者问题:
int main()
{
//创建两个线程
	sem_init(&m1,0,0);//m1读者
	sem_init(&m2,0,1);//m2作者
	//共同缓冲区
	char buf[100]="";
	pthread_t rtid,wtid;
	pthread_create(&rtid,NULL,reader,buf);	
	pthread_create(&wtid,NULL,author,buf);
//等待子线程结束
	pthread_join(rtid,NULL);
	pthread_join(wtid,NULL);
	return 0;
}

   通过信号量实现分别打印 A , B , C 的字符 .

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
//定义三个信号量
sem_t sa,sb,sc;
//线程函数
void* threadfun(void* arg)
{
	char ch=(int)arg;
	while(1)
	{
		if(ch=='A')
			sem_wait(&sa);
		else if(ch=='B')
			sem_wait(&sb);
		else
			sem_wait(&sc);
		printf("%c\n",ch);
		sleep(1);
		//v操作
		if(ch=='A')
			sem_post(&sb);
		else if(ch=='B')
			sem_post(&sc);
		else
			sem_post(&sa);
	}
	return NULL;
}
int main()
{
	sem_init(&sa,0,0);
	sem_init(&sb,0,0);
	sem_init(&sc,0,1);
//创建线程
	pthread_t tid[3];
	char ch='A';
	for(;ch<='C';ch++)
	{
		//创建
		pthread_create(&tid[ch-'A'],NULL,threadfun,(void*)ch);
	}
//等待线程结束
	for(ch=0;ch<=2;ch++)
		pthread_join(tid[ch],NULL);
	sem_destroy(&sa);
	sem_destroy(&sb);
	sem_destroy(&sc);
	return 0;
}

同步:指定为了完成某种任务而建立两个或两个以上的进程/线程,这些进程/线程在合作中需要“协调工作次序”进行有行的访问而出现等待所产生的制约关系。
    产生者/消费者 (模型)
    描述:一组生产者和一组消费者共享一块初始为空的空间;
              大小确定的缓冲区;
              生产者:当空间为满时,必须等待。否则可以生产车。
              消费者:只有缓冲区不为空是才能消费,否则必须等待。
              缓冲区一次只能访问一个进程(临界资源)
     问题:生产者与消费者对缓冲区是互斥关系(关系)。        
              生产者与消费又存在协同关系(必须先生产后消费)
     解决:1、互斥:互斥锁
                2、信号量:
              对缓冲区设置为空闲区数信号量和满区的数信号量。
        伪代码:
            semaphore  full=0        //满区的数量(当前实际量)
            semaphore  empty=100   //可存储量
            lock       mutex;        //锁
            //生产者:
            prodecer(){
                    while(1){
                        p(empty)//发现有仓库不为满,
                        lock(mutex);
                            add_source++;//生产并存放            
                        v(full)
                        unlock(mutex);            
                    }
            }
            //消费者:
            consumer(){
                while(1){
                    p(full)    //发现仓库车的数量是否为空
                    lock(mutex)
                        add_source--;//消费
                    v(empty);
                    unlock(mutex)
                }
            }

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<stdlib.h>
#include<unistd.h>
//定义信号量
sem_t empty,full;//empty仓库空闲区的数量 full为商品
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
//仓库:
struct store
{
	int buf[10];
	int ilen;
};
//定义结构体:
struct store s={0};
//生产者
void* productor(void* arg)
{
	while(1)
	{
		pthread_mutex_lock(&mutex);
		sem_wait(&empty);//p操作 有空闲区
		//生产
		sleep(rand()%2);//随机值
		printf("生产者生产的汽车标号为:%d",s.buf[s.ilen++]=rand());
		printf("-->当前一共有%d辆车\n",s.ilen);
		//货物数量+1
		sem_post(&full);//货物数量+1
		pthread_mutex_unlock(&mutex);
	}
}
//消费者
void* consumer(void* arg)
{
	while(1)
	{
		//P操作---买车(消耗货物)
		pthread_mutex_lock(&mutex);
		sem_wait(&full);
		//消费
		sleep(rand()%2);
		printf("购买的车的ID:%d",s.buf[--s.ilen]);
		printf("-->当前一共有%d辆车\n",s.ilen);
		sem_post(&empty);
		pthread_mutex_unlock(&mutex);
	}
}
int main()
{
//初始化
	sem_init(&empty,0,10);//空区数量
	sem_init(&full,0,0);  //商品数量
//创建两个线程:
	pthread_t ctid,ptid;//consumer	productor
	pthread_create(&ptid,NULL,productor,NULL);//生产者
	pthread_create(&ctid,NULL,consumer,NULL); //消费者
//等待
	pthread_join(ctid,NULL);
	pthread_join(ptid,NULL);
//销毁
	sem_destroy(&empty);
	sem_destroy(&full);
//销毁锁
	pthread_mutex_destroy(&mutex);
}

猜你喜欢

转载自blog.csdn.net/Superman___007/article/details/82861413
今日推荐