2024年1月31日发(作者:)

操作系统实验报告

实验六 信号量

一、 基本信息

二、 实验内容

生产者/消费者问题:在windows和linux操作系统上,利用各自操作系统提供的mutex和信号量机制,实现生产者/消费者问题。将设计一个程序来解决有限缓冲问题,期中生产者和消费者进程如图6.10与6.11所示。

三、 实验目的

1.通过实验,熟练掌握进程同步和互斥算法,理解生产者/消费者问题;

2.掌握windows和linux中多进程/线程的同步互斥方法的使用。

四、 设计思路和流程图

(1) 创建3个信号量:Mutex、Full、Empty

(2) 主程序创建10个生产者线程和10个消费者线程,之后休眠一段时间

(3) 生产者线程中,随机休息 一段时间后,生产一个随机数放入缓冲区里。利用信号量Mutex产生对缓冲区使用的互斥功能,利用Empty和Full信号量来对缓冲区进行增加项

(4) 消费者线程中,随机休息 一段时间后,消费一个缓冲区的数据。利用信号量Mutex产生对缓冲区使用的互斥功能,利用Empty和Full信号量来对缓冲区进行增加项

(5) 主程序休眠一段时间后,结束整个程序

五、 主要数据结构及其说明

(1)win32:

#include

#include

#include

#include

#include

#define BUFFER_SIZE 5

操作系统实验报告

int buffer[BUFFER_SIZE];

int cnt = 0;

HANDLE Mutex ,

void init()

{

}

int insert_item(int item, int order)

{//insert item into buffer

}

return flag;

ReleaseMutex(Mutex);

ReleaseSemaphore(Full, 1, NULL);

int flag = -1;

WaitForSingleObject(Empty, INFINITE);

WaitForSingleObject(Mutex, INFINITE);

//critical section

if(cnt < BUFFER_SIZE){

}

buffer[cnt++] = item;

flag = 0;//insert successfully

printf("producer %d produced %dn", order, cnt);

Mutex = CreateMutex(NULL, FALSE, NULL);//互斥锁初始化

Empty = CreateSemaphore(NULL, 5, 5, NULL);//信号量Emp初始化

Full = CreateSemaphore(NULL, 0, 5, NULL);//信号量Full初始化

Empty,

Full;

//互斥锁

//信号量emp

//信号量full

//现有产品数量

操作系统实验报告

int remove_item(int &item, int order)

{//remove object from buffer and place it in item

}

DWORD WINAPI producer(void *param)

{

srand((unsigned)time(NULL));

int random;

while(true)

{

}

Sleep((rand()%10 + 1) * 1000);

random = rand() % 50 + 1;

if(insert_item(random, (DWORD)param))

printf("report error conditionn");

//seed

return flag;

ReleaseMutex(Mutex);

ReleaseSemaphore(Empty, 1, NULL);

//critical section

if(cnt > 0)

{

}

item = buffer[cnt-1];

buffer[cnt-1] = 0;

flag = 0;

printf("consumer %d consumed %dn",order,cnt);

cnt--;

int flag = -1;

WaitForSingleObject(Full, INFINITE);

WaitForSingleObject(Mutex, INFINITE);

操作系统实验报告

}

DWORD WINAPI consumer(void *param)

{

}

int main(int argc, char *argv[])

{

DWORD ProducerThreadId[producerThs],

ConsumerThreadId[consumerThs];

HANDLE ProducerThreadHandles[producerThs],

ConsumerThreadHandles[consumerThs];

int i;

for(i = 0; i < producerThs; ++i)

{

//创建生产者线程

ProducerThreadHandles[i] = CreateThread(

memset(buffer, 0, sizeof buffer); //缓存区初始化

init();

//intialize semaphores

//生产者线程数量

static const int sleepTime = 10000, //睡眠多长时间终止

producerThs = 10,

consumerThs = 10; //消费者线程数量

srand((unsigned)time(NULL));

int random;

while(true)

{

}

Sleep((rand()%10 + 1) * 1000);

if(remove_item(random,(DWORD)param))

printf("report error conditionn");

//seed

操作系统实验报告

}

}

NULL,

0,

producer,

(LPVOID)i,

0,

&ProducerThreadId[i]);

//线程函数

//传递给线程函数的参数

for(i = 0; i < consumerThs; ++i)

{

}

Sleep(sleepTime);//主函数睡眠

//关闭所有子线程

for(i = 0; i < producerThs; ++i){

}

//exit(0);//终止应用程序

system("pause");

return 0;

CloseHandle(ProducerThreadHandles[i]);

CloseHandle(ConsumerThreadHandles[i]);

//创建消费者线程

ConsumerThreadHandles[i] = CreateThread(

NULL,

0,

consumer,

(LPVOID)i,

0,

&ConsumerThreadId[i]);

//线程函数

//传递给线程函数的参数

操作系统实验报告

(2)Pthread:

#include

#include

#include

#include

#include

#define BUFFER_SIZE 5

int buffer[BUFFER_SIZE];

int cnt = 0;

sem_t Empty;

sem_t Full;

void init()

{

}

int insert_item(int item, int order)

{//insert item into buffer

//critical section

if(cnt < BUFFER_SIZE)

{

int flag = -1;

sem_wait(&Empty);

pthread_mutex_lock(&Mutex);

pthread_mutex_init(&Mutex,NULL);

//互斥锁初始化

sem_init(&Empty,0,5);

//信号量Emp初始化

sem_init(&Full,0,0);

//信号量Full初始化

//信号量full

//信号量emp

//现有产品数量

//互斥锁 pthread_mutex_t Mutex;

操作系统实验报告

}

}

buffer[cnt++] = item;

flag = 0;//insert successfully

printf("producer %d produced %dn", order, cnt);

pthread_mutex_unlock(&Mutex);

sem_post(&Full);

return flag;

int remove_item(int &item, int order)

{//remove object from buffer and place it in item

int flag = -1;

sem_wait(&Full);

pthread_mutex_lock(&Mutex);

//critical section

if(cnt > 0)

{

item = buffer[cnt-1];

buffer[cnt-1] = 0;

flag = 0;

printf("consumer %d consumed %dn",order,cnt);

cnt--;

}

pthread_mutex_unlock(&Mutex);

sem_post(&Empty);

return flag;

}

void *producer(void *param)

{

srand((unsigned)time(NULL)); //seed

操作系统实验报告

int random;

while(1)

{

Sleep((rand()%10 + 1) * 1000);

random = rand() % 50 + 1;

if(insert_item(random, (int)param))

printf("report error conditionn");

}

}

void *consumer(void *param)

{

srand((unsigned)time(NULL)); //seed

int random;

while(1)

{

Sleep((rand()%10 + 1) * 1000);

if(remove_item(random,(int)param))

printf("report error conditionn");

}

}

int main(int argc, char *argv[])

{

init();

//intialize semaphores

//生产者线程数量

//消费者线程数量

static const int sleepTime = 10000, //睡眠多长时间终止

producerThs = 10,

consumerThs = 10;

int i,j;

pthread_t tid;

memset(buffer, 0, sizeof buffer); //缓存区初始化

操作系统实验报告

pthread_attr_t attr;

pthread_attr_init(&attr);

//创建生产者线程

for(i = 0; i < producerThs; ++i)

pthread_create(&tid,&attr,producer,i);

//创建消费者线程

for(j = 0; j < producerThs; ++j)

pthread_create(&tid,&attr,consumer,j);

Sleep(sleepTime);

//主函数睡眠

//exit(0);

//终止应用程序

system("pause");

return 0;

}

六、 程序运行时的初值和运行结果

七、 实验体会

通过实验,进一步学习了 Windows 和Linux 环境下互斥锁和信号量的实现方法,加深了对临界区问题和进程同步机制的理解,同时巩固利用Windows API 和PthreadAPI 进行多线程编程的方法。