一个线程专门 用于与客户端进行通信,一个线程用于将客户端发过来的消息放入自己定义的一个队列中。一个线程用于将队列中的消息取出然后进行运算。比如线程1 是专门负责与客户端进行通信的,接收客户端发过来的消息,线程2用于将消息放入队列中,线程3负责从队列中取出消息,进行运算处理,然后结果由线程1发回给客户端。(每次有新的客户端连接时,都给客户端分配一个标识,以便正确的进行通信。)这个涉及到多线程的同步问题。
涉及同步与互斥问题
queue req; // 请求队列
queue res; // 结果队列
mutex m_req; // 用于互斥访问请求队列
//以下两个变量用于同步请求
semaphore full_res = 0; // 这里的变量名改了下
semaphore empty_res = REQUEST_QUEUE_SIZE; // 同上
mutex m_res; // 用于互斥访问结果队列
//以下两个变量用于同步访问结果的队列
semaphore full_req = 0;
semaphore empty_req = RESUlT_QUEUE_SIZE;
// 用于接收客户端请求的线程
receive_request()
{
while(1){
P(empty_req); // 保证request queue 有足够的空间
receive(r); // 等待客户端的请求
P(m_req); // 互斥访问请求队列
put(req, r); // 将客户端的请求放入请求队列
V(m_req); // 释放“请求队列”的互斥锁
V(full_req); // 有请求到达,通知处理线程
}
}
// 用于处理客户端请求的线程
process_request()
{
while(1){
P(full_req); // 等待请求
P(m_req); // 互斥访问请求队列
get(req, &r); // 取出 客户的请求
V(m_req); // 释放“请求队列”的互斥锁
V(empty_req); // 处理掉一个请求,“请求队列”有新的空间可用
process(r); // 处理客户端的请求
P(empty_res); // 等待“结果队列”有空间可用
P(m_res); // 互斥访问结果队列
put(res, r); // 将刚才处理后得到的结果放入“结果队列”
V(m_res); // 释放“结果队列”的互斥锁
V(full_res); // 通知返回结果给客户的线程,有新的结果产生了
}
}
// 用于将结果返回给客户的线程
send_result()
{
while(1){
P(full_res); // 等待有结果产生
P(m_res); // 互斥访问“结果队列”
get(res, &r); // 取出结果
V(m_req); // 释放“结果队列”的互斥锁
V(empty_res); // 返回一个结果给客户后,“结果队列”有新的空间可用
send(r); // 将结果返回给客户
}
}
1.利用windows提供的API函数CreateSemaphore()创建信号量对象;
CreateThread()创建线程;
WaitForSingleObject()执行P操作;
ReleaseSemaphore()执行V操作;
WaitForMultipleObjects()主进程等待线程的结束等函数进行设计。
2.在Windows中,常见的同步对象有:信号量(Semaphore)、互斥量(Mutex) 。
使用这些对象都分为三个步骤,一是创建或者初始化;
接着请求该同步对象,
随即进入临界区,
这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。这些同步对象在主进程中创建,
在其子线程中都可
可cankao
2.《秒杀多线程第二篇 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别》
3.《秒杀多线程第三篇 原子操作 Interlocked系列函数》
8.《秒杀多线程第八篇 经典线程同步 信号量Semaphore》
9.《秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量》
10.《秒杀多线程第十篇 生产者消费者问题》
11.《秒杀多线程第十一篇 读者写者问题》
12.《秒杀多线程第十二篇 多线程同步内功心法——PV操作上》
13.《秒杀多线程第十三篇 多线程同步内功心法——PV操作下》即将发布
14.《秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock》