您的位置:首页 > 编程语言 > C语言/C++

线程与进程(c++ windows)

2014-05-12 09:33 190 查看
关于线程与进程的解释:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

#include <windows.h>
#include <iostream>
using namespace std;
// 对于不好重现的错误 修改起来是很麻烦的
//线程数据同步 一个线程在访问一个资源的时候 其他的线程不能对这个资源的访问
//windows 用互斥对象 来同步线程间的数据 实现同时只能有一个线程来访问这个数据
//互斥对象 内部一个 线程ID 记录当前那个线程拥有该互斥对象 还有一个计数器

//线程函数
DWORD WINAPI fun1Proc(
LPVOID lpParanrter
);

DWORD WINAPI fun2Proc(LPVOID lpPar);
int index = 0;
int tickets = 100;
HANDLE hMutex;
int main()
{
HANDLE hThread1;
hThread1 = CreateThread(NULL,0, fun1Proc, NULL, 0, NULL);
HANDLE hThread2;
hThread2 = CreateThread(nullptr, 0, fun2Proc, NULL, 0 , nullptr);
CloseHandle(hThread1);
CloseHandle(hThread2);
//while(index++ < 1000)
// cout << "main thread is running" << endl;
//暂停线程 参数的毫秒数的运行时间 同时放弃运行
//CPU会切换到其他线程运行 其他线程运行完 该线程会接着sleep下一步运行
//Sleep(2);

//创建一个匿名的互斥对象
//第二个参数为 false 当前没有线程 拥有互斥对象 操作系统会把它置为有信号状态
hMutex = CreateMutex(nullptr, false, nullptr);
//主线程退出 子线程会跟着退出 所以要保证 子线程运行时间内 主线程不能退出
//不能用死循环来代替 会占用CPU 时间片
Sleep(4000);
cin.get();
return 0;
}

DWORD WINAPI fun1Proc(
LPVOID lpParanrter
)
{
//线程函数执行完 线程就退出了 要想线程一直存在 要+一个循环
while(true)
{
//获取互斥对象状态 参数2 timeout(永远等待) 互斥对象状态为无信号 永远等待
//等待期间 其他线程会运行 直到互斥对象为有信号 才能继续运行
//如果互斥对象有信号 该函数会把 互斥对象的线程ID 置为该线程的ID
//同时把 互斥对象 置为 无信号
WaitForSingleObject(hMutex, INFINITE);
if(tickets > 0)
{
Sleep(1); // 会导致出错 卖出0这张票 加入互斥对象 不会出错
cout << "thread1 sell ticket : " << tickets-- << endl;
}
else
break;
//释放互斥对象 让互斥对象有信号 把互斥对象内部线程ID设置为0,
//其他的线程就可以得到互斥对象的所有权
//释放互斥对象 线程ID 会与 hMutex的线程ID 比较 相等才能释放互斥对象
//别的线程 是不能释放 当前线程的互斥对象的
ReleaseMutex(hMutex);
}
/*while(index++ < 1000)
cout << "thread1 is running" << endl;*/
return 0;
}

DWORD WINAPI fun2Proc(LPVOID lpPar)
{
//如果互斥对象请求和释放 放在while 循环外面 线程2会一直拥有该互斥对象 释放不了 因为下面是一直执行的循环
//WaitForSingleObject(hMutex, INFINITE);
while(true)
{
//互斥对象 内部有线程ID 与 引用计数 如果拥有互斥对象的线程 再请求互斥对象 还能请求
//引用计数会+1 ReleaseMutex 会让引用计数-1 引用计数为0 才会让 互斥对象有信号
//如果一个对象得到互斥对象之后 线程终止 没有释放互斥对象 操作系统会自动释放该互斥对象 最好自己释放
//WaitForSingleObject 返回值会 看出是 该互斥对象 终止的状态
WaitForSingleObject(hMutex, INFINITE);
if(tickets > 0)
{
Sleep(1); //会导致出错 卖出0这张票
cout << "thread2 sell ticket : " << tickets-- << endl;
}
else
break;
// 互斥对象 相当于只有一把钥匙 一个在使用 别人就不可以使用
ReleaseMutex(hMutex);
}
//ReleaseMutex(hMutex);
return 0;
}

//一些软件 如何自己已经有一个 程序实例了
//CreateMutex 创建一个有名字的互斥对象 如果已经有该互斥对象 就会返回以前的互斥对象的句柄
//getLastError 可以查看有名字的 互斥对象的句柄 是不是已经存在
//应用命名的互斥对象 会让程序 同时只能有一个实例在运行

//hMutex = CreateMutex(nullptr, true, "tickets");
//if(hMutex)
//{
// if(ERROR_ALREADY_EXISTS == GetLastError())
// {
// cout << "only instance can run!" << endl;
// return ;
// }
//}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: