操作系统 实验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

交互与结果:

相关推荐
ac.char2 分钟前
在 Ubuntu 上安装 Yarn 环境
linux·运维·服务器·ubuntu
敲上瘾3 分钟前
操作系统的理解
linux·运维·服务器·c++·大模型·操作系统·aigc
长弓聊编程21 分钟前
Linux系统使用valgrind分析C++程序内存资源使用情况
linux·c++
cherub.28 分钟前
深入解析信号量:定义与环形队列生产消费模型剖析
linux·c++
梅见十柒1 小时前
wsl2中kali linux下的docker使用教程(教程总结)
linux·经验分享·docker·云原生
Koi慢热1 小时前
路由基础(全)
linux·网络·网络协议·安全
传而习乎1 小时前
Linux:CentOS 7 解压 7zip 压缩的文件
linux·运维·centos
我们的五年1 小时前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
IT果果日记2 小时前
ubuntu 安装 conda
linux·ubuntu·conda
Python私教2 小时前
ubuntu搭建k8s环境详细教程
linux·ubuntu·kubernetes