操作系统实验报告
任课教师
姓名
学号
实验指导教师
。
。
。
。
年
月
日
实验五 线程与进程同步
一、实验目的
(1)学习使用现代通用操作系统提供的进程与线程同步机制进行程序设计
(2)加深对经典进程同步问题的理解
二、实验内容
(1)基于 LINUX 下多线程同步机制修改实验四的生产者消费者问题演示程序,保证程序
运行结果正确
三、程序设计
互斥量 work_mutex 是保护临界区 buffer,保证两个生产者和一个消费者不同时修改
buffer;
信号量 empty 是保护临界区 buffer 中未被生产者写入内容的区域,防止 buffer 中没有写
入内容的区域被消费者读;
信号量 full 是保护临界区 buffer 中已被生产者写入但未被消费者读的区域,防止两个生
产者重复对 buffer 的一个地方写入。
生产者线程流程图:
消费者线程流程图:
四、调试过程与结果分析
简要说明调试过程遇到的问题及解决的方法。
五、程序源代码
#include
#include
#include
#include
#include
#define BUFFERSIZE 6000
#define DATATOTAL 50000
void *consumer_thread (void *arg);
void *producer_thread (void *arg);
char message1[] = "1";
char message2[] = "-1";
char message3[] = "Consumer";
sem_t empty;
sem_t full;
int stop=2;
pthread_mutex_t work_mutex;
int
in = 0, out = 0;
int buffer[BUFFERSIZE];
int main ()
{
int res;
void *thread_result;
pthread_t p1_thread, p2_thread, c_thread;
res = sem_init(&full, 0, 0);//full 初始化为 0
if (res != 0)
{
perror("full emaphore initialization failed");
exit(EXIT_FAILURE);
}
res = sem_init(&empty, 0, BUFFERSIZE);
//empty 初始容量为 BUFFERSIZE
if (res != 0)
{
}
perror("empty emaphore initialization failed");
exit(EXIT_FAILURE);
//创建互斥量 work_mutex
res = pthread_mutex_init(&work_mutex, NULL);
if (res != 0)
{
}
perror("Mutex initialization failed");
exit(EXIT_FAILURE);
//创建一个消费者线程
res = pthread_create (&c_thread, NULL, consumer_thread, (void *) message3);
if (res != 0)
{
}
perror ("Thread creation failed");
exit (0);
//创建第一个生产者线程
res =pthread_create (&p1_thread, NULL, producer_thread, (void *) message1);
if (res != 0)
{
}
perror ("Thread creation failed");
exit (0);
//创建第二个生产者线程
res =pthread_create (&p2_thread, NULL, producer_thread, (void *) message2);
if (res != 0)
{
}
perror ("Thread creation failed");
exit (0);
printf ("Waiting for thread to finish...\n");
res = pthread_join (c_thread, &thread_result);
if (res != 0)
{
}
perror ("Thread join failed ");
exit (0);
printf ("Thread joined, it returned %s \n", (char *) thread_result);
sem_destroy(&empty);
sem_destroy(&full);
pthread_mutex_destroy(&work_mutex);
exit(0);
}
void *
producer_thread (void *arg)
{
int sign = atoi (((char *) arg));
long
running = 0;
int i,j;
printf (" producer thread_function is running,Argument was %s\n",(char *) arg);
while (running < DATATOTAL)
{
//down 信号量 empty
sem_wait(&empty);
//等待互斥量 work_mutex
pthread_mutex_lock(&work_mutex);
buffer[in] = sign * running;
in = (in +1) % BUFFERSIZE;
running++;
if (running==DATATOTAL) stop --;
//释放互斥量的所有权,允许其他线程访问 Buffer
pthread_mutex_unlock(&work_mutex);
//UP 信号量 full
sem_post(&full);
}
pthread_exit (" producer Thank you for the CPU time ");
}
void * consumer_thread (void *arg)
{
long
sum = 0;
int running = 1, consumerget = 0,pfull,pstop;
printf ("The consumer thread_function is running.\n");
while (running)
{
//down 信号量 full
sem_wait(&full);
pthread_mutex_lock(&work_mutex);
sum += buffer[out];
buffer[out] = 0;
out = (out + 1) % BUFFERSIZE;
pthread_mutex_unlock(&work_mutex);
//Up 信号量 full
sem_post(&empty);
//获取信号量 full 的值
sem_getvalue(&full,&pfull);
//如果信号量 full=0 并且达到总得循环次数,退出
if ((pfull == 0) && (stop == 0)) running = 0;
consumerget++;
}
}
fprintf (stderr,"consumer get: %d data items, sum:%d\n ", consumerget , sum);
pthread_exit (" consumer thank you for the CPU time ");
六、意见和建议
在实现线程同步时,可以不用 mutex 只用 semphore,实现程序如下:
#include
#include
#include
#include
#include
#define BUFFERSIZE 6000
#define DATATOTAL 50000
void *consumer_thread (void *arg);
void *producer_thread (void *arg);
char message1[] = "1";
char message2[] = "-1";
char message3[] = "Consumer";
sem_t empty;
sem_t full;
int stop=2;
sem_t amutex;
int
in = 0, out = 0;
int buffer[BUFFERSIZE];