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
交互與結果: