C语言实现进程同步与互斥
实验原理
(1)同步和互斥(生产者消费者问题)
同步是一种更为复杂的互斥,而互斥是一种特殊的同步。
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源
(2)信号量
在系统中,给予每一个进程一个信号量,代表每个进程目前的状态,未得到控制权的进程会在特定地方被强迫停下来,等待可以继续进行的信号到来。信号量又存在着两种操作,分别为V操作与P操作,V操作会增加信号量 S的数值,P操作会减少它。
(3)锁
在多线程编程中,操作系统引入了锁机制。通过锁机制,能够保证在多核多线程环境中,在某一个时间点上,只能有一个线程进入临界区代码,从而保证临界区中操作数据的一致性。
加锁过程用如下伪码表示:
1、read lock;
2、判断lock状态;(0表示资源可用,1表示资源已被占用)
3、如果已经加锁,失败返回;
4、把锁状态设置为上锁;
5、返回成功。
实验内容和方法
1.实验一(进程同步):
1)实验内容
分别创建两个工程,用来scanf和printf,从键盘输入,在屏幕上显示输入了多少个数,以此来实现进程同步。
2)代码以及代码分析
Scanf.c
#include<stdio.h>
#include<windows.h>
int main(){
HANDLE h;
int a=0;
h=CreateSemaphore(NULL,0,10,"scanfcount");
while(1)
{
scanf("%d",&a);
printf("%d",a);
ReleaseSemaphore(h,1,NULL);
}
}
Printf.c
#include<stdio.h>
#include<windows.h>
int main(){
HANDLE h;
int count=0;
h=CreateSemaphore(NULL,0,10,"scanfcount");
while(1)
{
WaitForSingleObject(h,INFINITE);
count++;
printf("%d",count);
}
}
3)实验结果截图
2.实验二(进程互斥):
1)实验内容
本次实验中,模拟两个线程实现信号量的争夺(无序性)。通过加锁实现在某一个时间点上,只能有一个线程进入临界区代码,从而保证临界区中操作数据的一致性。
2)代码及代码分析
MultiThread.c
#include<stdio.h>
#include<windows.h>
HANDLE m_hMutex;
//线程1
DWORD WINAPI ThreadFunc1(LPVOID lpParam)
{
int i;
for(i=0;i<5;i++)
{
WaitForSingleObject(m_hMutex,INFINITE);//进入临界区域
printf("Thread1 step1 in the critical section\n");
printf("Thread1 step2 in the critical section\n");
ReleaseMutex(m_hMutex);//释放
}
return 0;
}
//线程2
DWORD WINAPI ThreadFunc2(LPVOID lpParam)
{
int i;
for(i=0;i<5;i++)
{
WaitForSingleObject(m_hMutex,INFINITE);
printf("Thread2 step1 int the critical section\n");
printf("Thread2 step2 inthe critical section\n");
ReleaseMutex(m_hMutex);
}
return 0;
}
void main()
{
char c;
m_hMutex=CreateMutex(NULL,FALSE,NULL);
CreateThread(NULL, 0, ThreadFunc1, 0, 0, 0);
CreateThread(NULL, 0, ThreadFunc2, 0, 0, 0);
scanf("%c\n",&c);
}
3)实验结果截图