某寺庙有小和尚、老和尚若干。庙内有一水缸、由小和尚提水入缸,供老和尚饮用。水缸可容纳10桶水,每次入水、取水都为1桶,且不可同时进行。水取自同一井中,水井口很小,每次只能容纳一只水桶取水。设水桶个数为3个。试写出小和尚和老和尚的函数,假设有5个小和尚提水入缸,5个老和尚取水喝(每隔一定时间取水一次),分别用不同的线程模拟小和尚和老和尚,使他们能同步进行。(每个和尚一个线程)
Var mutex1, mutex2, empty, full, count: semaphore;
mutex1:=1; mutex2:=1;
empty:=10; full:=0; count:=3;
process 小和尚:
begin
repeat
wait(empty);
wait(count);
wait(mutex1);
从井中取水;
signal(mutex1);
wait(mutex2);
送水入水缸;
signal(mutex2);
signal(count);
signal(full);
until false;
end
process 老和尚:
begin
repeat
wait(full);
wait(count);
wait(mutex2);
从缸中取水;
signal(mutex2);
signal(empty);
signal(count);
until false;
end
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static int n = 0;
static object lockobj = new object();
static void wt(object i)
{
Random r = new Random((int)i ^ (int)DateTime.Now.Ticks);
Console.WriteLine("young monk " + i + " is started...");
while (true)
{
lock (lockobj)
{
if (n < 5)
{
n++;
Console.WriteLine("young monk " + i + " add, now have " + n);
}
}
Thread.Sleep(r.Next(3000, 5000));
}
}
static void ct(object i)
{
Random r = new Random((int)i ^ (int)DateTime.Now.Ticks);
Console.WriteLine("old monk " + i + " is started...");
while (true)
{
lock (lockobj)
{
if (n > 0)
{
n--;
Console.WriteLine("old monk " + i + " sub, now have " + n);
}
}
Thread.Sleep(r.Next(3000, 5000));
}
}
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
Thread t1 = new Thread(new ParameterizedThreadStart(wt));
t1.Start(i);
Thread t2 = new Thread(new ParameterizedThreadStart(ct));
t2.Start(i);
}
}
}
}
young monk 0 is started...
old monk 3 is started...
young monk 1 is started...
old monk 0 is started...
old monk 2 is started...
old monk 4 is started...
young monk 4 is started...
young monk 2 is started...
young monk 3 is started...
old monk 1 is started...
young monk 0 add, now have 1
old monk 3 sub, now have 0
young monk 2 add, now have 1
young monk 3 add, now have 2
old monk 2 sub, now have 1
old monk 0 sub, now have 0
young monk 4 add, now have 1
young monk 1 add, now have 2
old monk 2 sub, now have 1
old monk 3 sub, now have 0
young monk 4 add, now have 1
old monk 4 sub, now have 0
young monk 0 add, now have 1
young monk 2 add, now have 2
young monk 3 add, now have 3
young monk 1 add, now have 4
old monk 1 sub, now have 3
old monk 3 sub, now have 2
old monk 2 sub, now have 1
old monk 0 sub, now have 0
young monk 0 add, now have 1
young monk 4 add, now have 2
old monk 4 sub, now have 1
young monk 3 add, now have 2
young monk 2 add, now have 3
young monk 1 add, now have 4
old monk 1 sub, now have 3
old monk 3 sub, now have 2
old monk 2 sub, now have 1
old monk 0 sub, now have 0
young monk 0 add, now have 1
young monk 3 add, now have 2
old monk 1 sub, now have 1
young monk 1 add, now have 2
young monk 4 add, now have 3
old monk 4 sub, now have 2
young monk 2 add, now have 3
old monk 3 sub, now have 2
young monk 3 add, now have 3
old monk 0 sub, now have 2
young monk 0 add, now have 3
old monk 2 sub, now have 2
old monk 1 sub, now have 1
young monk 1 add, now have 2
young monk 4 add, now have 3
old monk 4 sub, now have 2
old monk 3 sub, now have 1
小和尚取水的间隔时间和老和尚喝水的间隔时间是多少?
//经典线程同步互斥问题
#include
#include
#include
long g_nNum; //全局资源
unsigned int __stdcall Fun(void *pPM); //线程函数
const int THREAD_NUM = 10; //子线程个数
int main()
{
g_nNum = 0;
HANDLE handle[THREAD_NUM];
int i = 0;
while (i < THREAD_NUM)
{
handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
i++;//等子线程接收到参数时主线程可能改变了这个i的值
}
//保证子线程已全部运行结束
WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
return 0;
}
unsigned int __stdcall Fun(void *pPM)
{
//由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来
int nThreadNum = *(int *)pPM; //子线程获取参数
Sleep(50);//some work should to do
g_nNum++; //处理全局资源
Sleep(0);//some work should to do
printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum);
return 0;
}