实验四 进程同步与互斥

本文由用户“遥不可及啊baby”分享发布 更新时间:2022-04-18 13:36:53 举报文档

以下为《实验四 进程同步与互斥》的无排版文字预览,完整格式请下载

下载前请仔细阅读文字预览以及下方图片预览。图片预览是什么样的,下载的文档就是什么样的。

实验四 进程同步与互斥

实验目的

掌握基本的同步与互斥算法,理解P,V操作。

理解生产者消费者模型,了解其它典型的同步互斥模型,如哲学家就餐、读者-写者模型等。

了解LINUX中进程同步互斥的实现方法,掌握相关函数的使用方法。

学习使用Windows中基本的同步对象,掌握相关API的使用方法。

了解Windows中多线程的并发执行机制,实现进程的同步与互斥。

PART 1 LINUX环境

一、相关知识介绍

1.常用线程函数

pthread线程库的使用,在源码中使用头文件 pthread.h,用gcc链接时加上 -lpthread 选项,链接线程库。

pthread_create 创建一个线程

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void*(*start_rtn)(void*),void * arg);

 参数1:产生线程的标识符

 参数2:所产生线程的属性,通常设为NULL

参数3:新的线程所执行的函数

参数4:新的线程函数的参数

函数返回值:若线程创建成功则返回0,否则返 回-1.

pthread_exit 线程自行退出

pthread_join 其它线程等待某一个线程退出

int pthread_join( pthread_t thread , void **value_ptr);

 参数1:等待线程的标识符

 参数2:用户定义的指针,用来存储被等待线程的返回值

函数返回值:若执行成功则返回0,失败返回错误号, 如果一个线程要等待另一个线程的终止,则使用该函数

pthread_cancel 其它线程强行杀死某一个线程

2. 互斥锁使用方法

(1) 互斥锁操作相关函数

pthread_mutex_init: 互斥量初始化

pthread_mutex_lock: 互斥量加锁

pthread_mutex_unlock: 释放互斥锁

pthread_mutex_destroy: 释放互斥锁资源

(2)使用互斥锁对临界区进行操作的方法:

使用函数pthread_mutex_lock进行加锁

临界区操作

使用函数pthread_mutex_unlock释放互斥锁

3. 信号量使用方法

(1) 信号量相关函数

信号量的数据类型为sem_t

#include

相关函数: sem_init 、sem_wait、 sem_post、 sem_destroy

int sem_init (sem_t *sem, int pshared, unsigned int value);

参数1: 待初始化的信号量

参数2: 信号量的类型。如果值为0,表示是当前进程的局部信号量,否则是其它进程可以共享该信号量。 LINUX线程一般不支持进程间共享信号量,该值设为0.

参数3:信号量的初始值。

调用成功时返回0,失败返回-1.

int sem_wait(sem_t * sem);

参数: 由sem_init调用初始化的信号量对象的指针 sem的值减1等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。

成功返回0,失败返回-1

int sem_post(sem_t * sem);

参数: 由sem_init调用初始化的信号量对象的指针

释放信号量,让信号量的值加1。相当于V操作。

int sem_destroy(sem_t * sem);

参数: 由sem_init调用初始化的信号量对象的指针

归还自己占据的一切资源。 在清理信号量的时候如果还有线程在等待它,用户就会收到一个错误。

(2) 信号量使用方法

声明一个信号量sem_t my_sem;

初始化信号量sem_init(& my_sem,0,1);

sem_post和sem_wait函数配合使用来达到线程同步

释放信号量int sem_destroy (& my_sem);

二、实验内容

1. 生产者-消费者问题

(1)以下给出生产者-消费者问题的基本框架,未实现同步互斥控制,仔细查看程序运行结果,分析原因。

#include

#include

#include

#include

#include

#include

#define N 4 // 消费者或者生产者的数目

#define M 20 // 缓冲数目

int in = 0; // 生产者放置产品的位置

int out = 0; // 消费者取产品的位置

char buff[M]; // 缓冲区

int producter_id = 0; //生产者id

int consumer_id = 0; //消费者id

/* 打印缓冲情况 */

void print()

{

int i;

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

printf("%c ", buff[i]);

printf("\n");

}

/* 生产者方法 */

void *producter()

{

int id = ++producter_id;

while(1)

{

// 用sleep的数量可以调节生产和消费的速度

sleep(2);

char data;

data=rand()%26+65;

in = in % M;

printf("生产者进程%d在%2d位置产生数据%c: ", id,in,data);

buff[in] = data;

print();

++in;

}

}

/* 消费者方法 */

void *consumer()

{

char data;

int id = ++consumer_id;

while(1)

{

// 用sleep的数量可以调节生产和消费的速度

sleep(1);

out = out % M;

data=buff[out];

printf("消费者进程%d在%2d位置消费数据%c: ",id, out,data);

buff[out] = '*';

print();

++out;

}

}

int main()

{

pthread_t p[N];

pthread_t c[N];

int i;

int ret[N];

for(i=0; i

以上为《实验四 进程同步与互斥》的无排版文字预览,完整格式请下载

下载前请仔细阅读上面文字预览以及下方图片预览。图片预览是什么样的,下载的文档就是什么样的。

图片预览