当前位置:   article > 正文

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

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

1、并发线程同步与互斥

源程序:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. int num=30,count=10;
  7. pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER;
  8. void *sub1(void *arg) {
  9. int i = 0,tmp;
  10. for (; i <count; i++)
  11. {
  12. pthread_mutex_lock(&mylock); tmp=num-1;
  13. usleep(13);
  14. num=tmp; pthread_mutex_unlock(&mylock); printf("线程1 num减1后值为: %d\n",num);
  15. }
  16. return ((void *)0);
  17. }
  18. void *sub2(void *arg){
  19. int i=0,tmp;
  20. for(;i<count;i++)
  21. {
  22. pthread_mutex_lock(&mylock);
  23. tmp=num-1;
  24. usleep(31);
  25. num=tmp;
  26. pthread_mutex_unlock(&mylock);
  27. printf("线程2 num减1后值为: %d\n",num);
  28. }
  29. return ((void *)0);
  30. }
  31. int main(int argc, char** argv) {
  32. pthread_t tid1,tid2;
  33. int err,i=0,tmp;
  34. void *tret;
  35. err=pthread_create(&tid1,NULL,sub1,NULL);
  36. if(err!=0)
  37. {
  38. printf("pthread_create error:%s\n",strerror(err));
  39. exit(-1);
  40. }
  41. err=pthread_create(&tid2,NULL,sub2,NULL);
  42. if(err!=0)
  43. {
  44. printf("pthread_create error:%s\n",strerror(err));
  45. exit(-1);
  46. }
  47. for(;i<count;i++)
  48. {
  49. pthread_mutex_lock(&mylock); tmp=num-1;
  50. usleep(5);
  51. num=tmp;
  52. pthread_mutex_unlock(&mylock);
  53. printf("main num减1后值为: %d\n",num);
  54. }
  55. printf("两个线程运行结束\n");
  56. err=pthread_join(tid1,&tret);
  57. if(err!=0)
  58. {
  59. printf("can not join with thread1:%s\n",strerror(err));
  60. exit(-1);
  61. }
  62. printf("thread 1 exit code %d\n",(int)tret);
  63. err=pthread_join(tid2,&tret);
  64. if(err!=0)
  65. {
  66. printf("can not join with thread1:%s\n",strerror(err));
  67. exit(-1);
  68. }
  69. printf("thread 2 exit code %d\n",(int)tret);
  70. return 0;
  71. }

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

运行命令:./threadmutex

交互与结果:

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

源程序:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <pthread.h>
  5. #include <unistd.h>
  6. #include <signal.h>
  7. #include <semaphore.h>
  8. #define Maxbuf 10 //缓冲单元数目
  9. #define TimesOfOp 10 //生产者、消费者循环读写缓冲区的次数
  10. #define true 1
  11. #define false 0
  12. #define historynum 100 //生产者、消费者读写历史记录数目
  13. struct Circlebuf //循环缓冲队列结构
  14. {
  15. int read; //读指针
  16. int write; //写指针
  17. int buf[Maxbuf]; //缓冲区
  18. } circlebuf;
  19. sem_t mutex; //互斥信号量
  20. sem_t empty; //空白缓冲区同步信号量
  21. sem_t full; //满缓冲区同步信号量
  22. char writehistory[historynum][30];//写历史
  23. char readhistory[historynum][30];//读历史
  24. int writehistorycount=0; //写历史计数器
  25. int readhistorycount=0; //读历史计数器
  26. char history[historynum][30]; //缓冲区操作历史
  27. int historycount=0; //缓冲区操作历史计数器
  28. void writeCirclebuf(struct Circlebuf *circlebuf,int *value) //向缓冲区中写一个值
  29. {
  30. circlebuf->buf[circlebuf->write]=(*value);
  31. sleep(1);
  32. circlebuf->write=(circlebuf->write+1)%Maxbuf;
  33. }
  34. int readCirclebuf(struct Circlebuf *circlebuf)
  35. {
  36. int value=0;
  37. value=circlebuf->buf[circlebuf->read]; sleep(1); circlebuf->buf[circlebuf->read]=0; circlebuf->read=(circlebuf->read+1)%Maxbuf; return value;
  38. }
  39. void sigend(int sig)
  40. {
  41. exit(0);
  42. }
  43. void * productThread(void *i)
  44. {
  45. int *n=(int *)i;
  46. int t=TimesOfOp;
  47. int writeptr;
  48. while(t--)
  49. { sem_wait(&empty);
  50. sem_wait(&mutex);
  51. writeCirclebuf(&circlebuf,n);
  52. if(circlebuf.write>0) writeptr=circlebuf.write-1;
  53. else writeptr= Maxbuf-1;
  54. sprintf(writehistory[writehistorycount++],"生产者%d:缓冲区%d=%d", *n,writeptr,*n);
  55. sprintf(history[historycount++],"生产者%d:缓冲区%d=%d\n", *n,writeptr, *n);
  56. sem_post(&mutex);
  57. sem_post(&full);
  58. sleep(1);
  59. }
  60. }
  61. void * consumerThread(void *i)
  62. {
  63. int *n=(int *)i;
  64. int t=TimesOfOp; int value=0; int readptr; while(t--)
  65. {
  66. sem_wait(&full); sem_wait(&mutex);
  67. value=readCirclebuf(&circlebuf); if(circlebuf.read>0) readptr=circlebuf.read-1;
  68. else readptr= Maxbuf-1;
  69. sprintf(readhistory[readhistorycount++], "消费者%d:缓冲区%d=%d\n", *n,readptr,value);
  70. sprintf(history[historycount++],"消费者%d:缓冲区%d=%d\n", *n,readptr,value);
  71. sem_post(&mutex); sem_post(&empty); sleep(1); }
  72. }
  73. int main()
  74. {
  75. int i,max;
  76. int ConsNum=0,ProdNum=0,ret;
  77. sem_init(&mutex,0,1);
  78. sem_init(&empty,0,Maxbuf);
  79. sem_init(&full,0,0);
  80. signal(SIGINT, sigend);
  81. signal(SIGTERM, sigend);
  82. circlebuf.read=circlebuf.write=0;
  83. for(i=0;i<Maxbuf;i++)
  84. circlebuf.buf[i]=0;
  85. printf("请输入生产者线程的数目 :");
  86. scanf("%d",&ProdNum);
  87. int *pro=(int*)malloc(ProdNum*sizeof(int));
  88. pthread_t *proid=(pthread_t*)malloc(ProdNum*sizeof(pthread_t));
  89. printf("请输入消费者线程的数目 :");
  90. scanf("%d",&ConsNum);
  91. int *con=(int*)malloc(ConsNum*sizeof(int));
  92. pthread_t *conid=(pthread_t*)malloc(ConsNum*sizeof(pthread_t));
  93. for(i=1;i<=ConsNum;i++)
  94. {
  95. con[i-1]=i;
  96. ret=pthread_create(&conid[i],NULL,consumerThread,(void *)&con[i-1]);
  97. if(ret!=0)
  98. {
  99. printf("Create thread error");
  100. exit(1);
  101. }
  102. }
  103. for(i=1;i<=ProdNum;i++)
  104. {
  105. pro[i-1]=i;
  106. ret=pthread_create(&proid[i],NULL,productThread,(void *)&pro[i-1]);
  107. if(ret!=0)
  108. {
  109. printf("Create thread error");
  110. exit(1);
  111. }
  112. }
  113. sleep((ConsNum+ ProdNum)*10);
  114. if (writehistorycount>readhistorycount) max=writehistorycount;
  115. else max=readhistorycount;
  116. for(i=0;i<max;i++)
  117. if ((i<writehistorycount) && (i<readhistorycount))
  118. printf("%s | %s\n",writehistory[i],readhistory[i]);
  119. else if (i<writehistorycount)
  120. printf("%s | %s\n",writehistory[i]," ");
  121. else printf("%s | %s\n"," ",readhistory[i]);
  122. printf("*************缓冲池的操作历史为:******************\n");
  123. for(i=0;i<historycount;i++) printf("%s",history[i]);
  124. sem_destroy(&mutex);
  125. sem_destroy(&empty);
  126. sem_destroy(&full);
  127. }

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

运行命令:./pc1

交互与结果:

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

源程序:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <pthread.h>
  5. #include <unistd.h>
  6. #include <signal.h>
  7. #define Maxbuf 10 //缓冲单元数目
  8. #define TimesOfOp 10 //生产者、消费者循环读写缓冲区的次数
  9. #define true 1
  10. #define false 0
  11. #define historynum 100 //生产者、消费者读写历史记录数目
  12. struct Circlebuf //循环缓冲队列结构
  13. {
  14. int read; //读指针
  15. int write; //写指针
  16. int buf[Maxbuf]; //缓冲区
  17. } circlebuf;
  18. char writehistory[historynum][30];//写历史
  19. char readhistory[historynum][30];//读历史
  20. int writehistorycount=0; //写历史计数器
  21. int readhistorycount=0; //读历史计数器
  22. char history[historynum][30]; //缓冲区操作历史
  23. int historycount=0; //缓冲区操作历史计数器
  24. void writeCirclebuf(struct Circlebuf *circlebuf,int *value) //向缓冲区中写一个值
  25. {
  26. circlebuf->buf[circlebuf->write]=(*value);
  27. sleep(1);
  28. circlebuf->write=(circlebuf->write+1)%Maxbuf;
  29. }
  30. int readCirclebuf(struct Circlebuf *circlebuf)
  31. {
  32. int value=0;
  33. value=circlebuf->buf[circlebuf->read]; sleep(1);
  34. circlebuf->buf[circlebuf->read]=0; circlebuf->read=(circlebuf->read+1)%Maxbuf; return value;
  35. }
  36. void sigend(int sig)
  37. {
  38. exit(0);
  39. }
  40. void * productThread(void *i)
  41. {
  42. int *n=(int *)i;
  43. int t=TimesOfOp;
  44. int writeptr;
  45. while(t--)
  46. {
  47. writeCirclebuf(&circlebuf,n);
  48. if(circlebuf.write>0) writeptr=circlebuf.write-1;
  49. else writeptr= Maxbuf-1;
  50. sprintf(writehistory[writehistorycount++],"生产者%d:缓冲区%d=%d", *n,writeptr,*n);
  51. sprintf(history[historycount++],"生产者%d:缓冲区%d=%d\n", *n,writeptr, *n);
  52. sleep(1);
  53. }
  54. }
  55. void * consumerThread(void *i)
  56. {
  57. int *n=(int *)i;
  58. int t=TimesOfOp; int value=0; int readptr; while(t--)
  59. {
  60. value=readCirclebuf(&circlebuf); if(circlebuf.read>0) readptr=circlebuf.read-1;
  61. else readptr= Maxbuf-1;
  62. sprintf(readhistory[readhistorycount++], "消费者%d:缓冲区%d=%d\n", *n,readptr,value);
  63. sprintf(history[historycount++],"消费者%d:缓冲区%d=%d\n", *n,readptr,value);
  64. sleep(1);
  65. }
  66. }
  67. int main()
  68. {
  69. int i,max;
  70. int ConsNum=0,ProdNum=0,ret;
  71. circlebuf.read=circlebuf.write=0;
  72. for(i=0;i<Maxbuf;i++)
  73. circlebuf.buf[i]=0;
  74. printf("请输入生产者线程的数目 :");
  75. scanf("%d",&ProdNum);
  76. int *pro=(int*)malloc(ProdNum*sizeof(int));
  77. pthread_t *proid=(pthread_t*)malloc(ProdNum*sizeof(pthread_t));
  78. printf("请输入消费者线程的数目 :");
  79. scanf("%d",&ConsNum);
  80. int *con=(int*)malloc(ConsNum*sizeof(int));
  81. pthread_t *conid=(pthread_t*)malloc(ConsNum*sizeof(pthread_t));
  82. for(i=1;i<=ConsNum;i++)
  83. {
  84. con[i-1]=i;
  85. ret=pthread_create(&conid[i],NULL,consumerThread,(void *)&con[i-1]);
  86. if(ret!=0)
  87. {
  88. printf("Create thread error");
  89. exit(1);
  90. }
  91. }
  92. for(i=1;i<=ProdNum;i++)
  93. {
  94. pro[i-1]=i;
  95. ret=pthread_create(&proid[i],NULL,productThread,(void *)&pro[i-1]);
  96. if(ret!=0)
  97. {
  98. printf("Create thread error");
  99. exit(1);
  100. }
  101. }
  102. sleep((ConsNum+ ProdNum)*10);
  103. if (writehistorycount>readhistorycount) max=writehistorycount;
  104. else max=readhistorycount;
  105. for(i=0;i<max;i++)
  106. if ((i<writehistorycount) && (i<readhistorycount))
  107. printf("%s | %s\n",writehistory[i],readhistory[i]);
  108. else if (i<writehistorycount)
  109. printf("%s | %s\n",writehistory[i]," ");
  110. else printf("%s | %s\n"," ",readhistory[i]);
  111. printf("*************缓冲池的操作历史为:******************\n");
  112. for(i=0;i<historycount;i++) printf("%s",history[i]);
  113. }

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

运行命令:./pc2

交互与结果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/682611
推荐阅读
相关标签
  

闽ICP备14008679号