操作系统 实验29 同步与互斥

1、并发线程同步与互斥

源程序:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
int num=30,count=10;
pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER; 
void *sub1(void *arg) {
    int i = 0,tmp;
    for (; i <count; i++)
    {
		pthread_mutex_lock(&mylock);    			tmp=num-1;
	 	usleep(13);
        	num=tmp;								pthread_mutex_unlock(&mylock);	        		printf("线程1 num减1后值为: %d\n",num);
    }
	return ((void *)0);
}
void *sub2(void *arg){
    int i=0,tmp;
    for(;i<count;i++)
    {
		pthread_mutex_lock(&mylock);
        	tmp=num-1;
	 	usleep(31);
        	num=tmp;
	 	pthread_mutex_unlock(&mylock);
        	printf("线程2 num减1后值为: %d\n",num);
    }
    return ((void *)0);
}
int main(int argc, char** argv) {
    pthread_t tid1,tid2;
    int err,i=0,tmp;
    void *tret;
    err=pthread_create(&tid1,NULL,sub1,NULL);
    if(err!=0)
    {
    	printf("pthread_create error:%s\n",strerror(err));
        exit(-1);
    }
err=pthread_create(&tid2,NULL,sub2,NULL);
    if(err!=0)
    {
    	printf("pthread_create error:%s\n",strerror(err));
        exit(-1);
    }
 for(;i<count;i++)
    {
		pthread_mutex_lock(&mylock);     			tmp=num-1;
		usleep(5);	
     		num=tmp;		
	 	pthread_mutex_unlock(&mylock); 
        	printf("main num减1后值为: %d\n",num);
    }
    printf("两个线程运行结束\n");
    err=pthread_join(tid1,&tret);
if(err!=0)
    {
    	printf("can not join with thread1:%s\n",strerror(err));
        exit(-1);
    }
    printf("thread 1 exit code %d\n",(int)tret);
 err=pthread_join(tid2,&tret);
    if(err!=0)
    {
    	printf("can not join with thread1:%s\n",strerror(err));
        exit(-1);
    }
    printf("thread 2 exit code %d\n",(int)tret);
    return 0;
}

编译链接命令:gcc threadmutex.c -o threadmutex -lpthread

运行命令:./threadmutex

交互与结果:

2、生产者-消费者同步与互斥试验

源程序:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
#define Maxbuf 10		//缓冲单元数目
#define TimesOfOp 10		//生产者、消费者循环读写缓冲区的次数
#define true 1
#define false 0
#define historynum 100	//生产者、消费者读写历史记录数目
struct Circlebuf	//循环缓冲队列结构
{
	int read; 			//读指针
	int write; 		//写指针
	int buf[Maxbuf]; 	//缓冲区
} circlebuf;
sem_t mutex;			//互斥信号量
sem_t empty; 			//空白缓冲区同步信号量
sem_t full; 			//满缓冲区同步信号量
char writehistory[historynum][30];//写历史
char readhistory[historynum][30];//读历史
int writehistorycount=0;		//写历史计数器
int readhistorycount=0; 		//读历史计数器
char history[historynum][30];	//缓冲区操作历史
int historycount=0;		//缓冲区操作历史计数器
void writeCirclebuf(struct Circlebuf *circlebuf,int *value) //向缓冲区中写一个值
{
	circlebuf->buf[circlebuf->write]=(*value);
	sleep(1);							
	circlebuf->write=(circlebuf->write+1)%Maxbuf; 
}
int readCirclebuf(struct Circlebuf *circlebuf)
{
	int value=0;
	value=circlebuf->buf[circlebuf->read];		sleep(1);								circlebuf->buf[circlebuf->read]=0; 			circlebuf->read=(circlebuf->read+1)%Maxbuf; 	return value;
}
void sigend(int sig)
{
	exit(0);
}
void * productThread(void *i)
{
	int *n=(int *)i;
	int t=TimesOfOp;
	int writeptr;

	while(t--)
	{	sem_wait(&empty);
		sem_wait(&mutex);
		writeCirclebuf(&circlebuf,n);
		if(circlebuf.write>0) writeptr=circlebuf.write-1;
		else writeptr= Maxbuf-1;
	sprintf(writehistory[writehistorycount++],"生产者%d:缓冲区%d=%d", *n,writeptr,*n);
		sprintf(history[historycount++],"生产者%d:缓冲区%d=%d\n", *n,writeptr, *n);
		sem_post(&mutex);
		sem_post(&full);
		sleep(1);
	}
}
void * consumerThread(void *i)
{
	int *n=(int *)i;
	int t=TimesOfOp;						int value=0;							int readptr;							while(t--)
	{
		sem_wait(&full);						sem_wait(&mutex);
		value=readCirclebuf(&circlebuf);			if(circlebuf.read>0) readptr=circlebuf.read-1;	
		else readptr= Maxbuf-1;
		sprintf(readhistory[readhistorycount++], "消费者%d:缓冲区%d=%d\n", *n,readptr,value);
		sprintf(history[historycount++],"消费者%d:缓冲区%d=%d\n", *n,readptr,value);
		sem_post(&mutex);						sem_post(&empty);						sleep(1);							}
}
int main()
{
	int i,max;
	int ConsNum=0,ProdNum=0,ret;
	sem_init(&mutex,0,1);
	sem_init(&empty,0,Maxbuf);
	sem_init(&full,0,0);	
	signal(SIGINT, sigend);
	signal(SIGTERM, sigend);
	circlebuf.read=circlebuf.write=0;
	for(i=0;i<Maxbuf;i++)
		circlebuf.buf[i]=0;
	printf("请输入生产者线程的数目 :");
	scanf("%d",&ProdNum);
	int *pro=(int*)malloc(ProdNum*sizeof(int));
	pthread_t *proid=(pthread_t*)malloc(ProdNum*sizeof(pthread_t));
  	printf("请输入消费者线程的数目 :");
 	scanf("%d",&ConsNum);
	int *con=(int*)malloc(ConsNum*sizeof(int));
	pthread_t *conid=(pthread_t*)malloc(ConsNum*sizeof(pthread_t));
	for(i=1;i<=ConsNum;i++)
	{
		con[i-1]=i;
	ret=pthread_create(&conid[i],NULL,consumerThread,(void *)&con[i-1]);
		if(ret!=0)
		{
			printf("Create thread error");
			exit(1);
		}
	}
	for(i=1;i<=ProdNum;i++)
	{
		pro[i-1]=i;
	ret=pthread_create(&proid[i],NULL,productThread,(void *)&pro[i-1]);
		if(ret!=0)
		{
			printf("Create thread error");
			exit(1);
		}
	}
	sleep((ConsNum+ ProdNum)*10);
	if (writehistorycount>readhistorycount) max=writehistorycount;
	else max=readhistorycount;
	
	for(i=0;i<max;i++)
		if ((i<writehistorycount) && (i<readhistorycount))
			printf("%s | %s\n",writehistory[i],readhistory[i]);
		else if (i<writehistorycount)
			printf("%s | %s\n",writehistory[i]," ");
		else 	printf("%s | %s\n"," ",readhistory[i]);
	printf("*************缓冲池的操作历史为:******************\n");
	for(i=0;i<historycount;i++)  printf("%s",history[i]);
	sem_destroy(&mutex);	
	sem_destroy(&empty);
	sem_destroy(&full);
}

编译链接命令:gcc pc1.c -o pc1 -lpthread

运行命令:./pc1

交互与结果:

3、生产者-消费者未加同步与互斥机制的运行试验

源程序:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#define Maxbuf 10       //缓冲单元数目
#define TimesOfOp 10    //生产者、消费者循环读写缓冲区的次数
#define true 1
#define false 0
#define historynum 100  //生产者、消费者读写历史记录数目
struct Circlebuf    //循环缓冲队列结构
{
    int read;            //读指针
    int write;       //写指针
    int buf[Maxbuf];    //缓冲区
} circlebuf;

char writehistory[historynum][30];//写历史
char readhistory[historynum][30];//读历史
int writehistorycount=0;        //写历史计数器
int readhistorycount=0;         //读历史计数器
char history[historynum][30];    //缓冲区操作历史
int historycount=0;        //缓冲区操作历史计数器

void writeCirclebuf(struct Circlebuf *circlebuf,int *value) //向缓冲区中写一个值
{
    circlebuf->buf[circlebuf->write]=(*value);
    sleep(1);                           
    circlebuf->write=(circlebuf->write+1)%Maxbuf; 
}
int readCirclebuf(struct Circlebuf *circlebuf)
{
    int value=0;
    value=circlebuf->buf[circlebuf->read];        sleep(1);                                
    circlebuf->buf[circlebuf->read]=0;            circlebuf->read=(circlebuf->read+1)%Maxbuf;     return value;
}

void sigend(int sig)
{
    exit(0);
}

void * productThread(void *i)
{
    int *n=(int *)i;
    int t=TimesOfOp;
    int writeptr;
    while(t--)
    {   
        writeCirclebuf(&circlebuf,n);
        if(circlebuf.write>0) writeptr=circlebuf.write-1;
        else writeptr= Maxbuf-1;
    sprintf(writehistory[writehistorycount++],"生产者%d:缓冲区%d=%d", *n,writeptr,*n);
        sprintf(history[historycount++],"生产者%d:缓冲区%d=%d\n", *n,writeptr, *n);
        sleep(1);
    }
}

void * consumerThread(void *i)
{
    int *n=(int *)i;
    int t=TimesOfOp;                        int value=0;                            int readptr;                            while(t--)
    {
        value=readCirclebuf(&circlebuf);            if(circlebuf.read>0) readptr=circlebuf.read-1;    
        else readptr= Maxbuf-1;
        sprintf(readhistory[readhistorycount++], "消费者%d:缓冲区%d=%d\n", *n,readptr,value);
        sprintf(history[historycount++],"消费者%d:缓冲区%d=%d\n", *n,readptr,value);
        sleep(1);
    }
}

int main()
{
    int i,max;
    int ConsNum=0,ProdNum=0,ret;
    circlebuf.read=circlebuf.write=0;
    for(i=0;i<Maxbuf;i++)
        circlebuf.buf[i]=0;
    printf("请输入生产者线程的数目 :");
    scanf("%d",&ProdNum);
    int *pro=(int*)malloc(ProdNum*sizeof(int));
    pthread_t *proid=(pthread_t*)malloc(ProdNum*sizeof(pthread_t));
    printf("请输入消费者线程的数目 :");
    scanf("%d",&ConsNum);
    int *con=(int*)malloc(ConsNum*sizeof(int));
    pthread_t *conid=(pthread_t*)malloc(ConsNum*sizeof(pthread_t));
    for(i=1;i<=ConsNum;i++)
    {
        con[i-1]=i;
    ret=pthread_create(&conid[i],NULL,consumerThread,(void *)&con[i-1]);
        if(ret!=0)
        {
            printf("Create thread error");
            exit(1);
        }
    }
    for(i=1;i<=ProdNum;i++)
    {
        pro[i-1]=i;
    ret=pthread_create(&proid[i],NULL,productThread,(void *)&pro[i-1]);
        if(ret!=0)
        {
            printf("Create thread error");
            exit(1);
        }
    }
    sleep((ConsNum+ ProdNum)*10);
    if (writehistorycount>readhistorycount) max=writehistorycount;
    else max=readhistorycount;
    for(i=0;i<max;i++)
        if ((i<writehistorycount) && (i<readhistorycount))
            printf("%s | %s\n",writehistory[i],readhistory[i]);
        else if (i<writehistorycount)
            printf("%s | %s\n",writehistory[i]," ");
        else    printf("%s | %s\n"," ",readhistory[i]);
    printf("*************缓冲池的操作历史为:******************\n");
    for(i=0;i<historycount;i++)  printf("%s",history[i]);
}

编译链接命令:gcc pc2.c -o pc2 -lpthread

运行命令:./pc2

交互与结果:

相关推荐
零涂毕业设计2 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud1232 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
SakitamaX2 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.2 小时前
Linux系统管理
linux·运维
阿龙的工作记录3 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手3 小时前
Linux的基本指令
linux·运维·服务器
撩得Android一次心动5 小时前
Linux编程笔记3【个人用】
linux·笔记
OpenPomeloxCommunity5 小时前
3. Linux 同步机制之 spinlock 设计与实现(一):通用层
linux
念恒123066 小时前
网络基础
linux·网络·c++
皮卡狮6 小时前
Linux静态库和动态库详解
linux