模拟火车票购票系统的简单多线程程序

#include<windows.h>
#include<iostream.h>

//线程1入口函数原型声明
DWORD WINAPI Fun1Proc( 
LPVOID lpParameter // thread data
);

//线程2入口函数原型声明
DWORD WINAPI Fun2Proc( 
LPVOID lpParameter // thread data
);


int index=0;
int tickets=100;
HANDLE hMutex;//创建互斥对象句柄
void main()
{
HANDLE hThread1,hThread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);//Fun1Proc为线程的入口函数
CloseHandle(hThread1);/*关闭线程句柄,,并没有终止新创建的线程,只是表示在主线程中我们对新创建
的线程的引用不感兴趣,所以将它关闭当我们关闭句柄的时候,系统会递减新线程的内核对象的使用技术,
当我们所创建的线程执行完毕之后,系统也会递减线程内核对象的使用技术,当使用技术为0的时候,系统
就会释放线程内核对象,如果我们在主线程中没有关闭线程句柄,那么始终都会保留一个引用,那么这样的话
线程内核对象的引用技术就不会为0,即使我们这个线程执行完毕,线程内核对象也不会被释放,只有等到进程
终止的时候,系统才会为这些残留的对象做清理工作,所以我们应该再不再使用线程的时候将其关闭掉,让这个
线程的内核对象的引h用对象减1
*/
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread2);
// while(index++<1000)
// cout<<"main thread is running"<<endl;
// Sleep(10);//使主线程暂停执行10毫秒,让线程1有机会运行。
hMutex=CreateMutex(NULL,FALSE,NULL);//创建一个匿名的互斥对象
Sleep(4000);//使主线程暂停执行10毫秒,让线程1有机会运行,此时主线程不占用cpu的执行时间

}


//线程1实现代码
DWORD WINAPI Fun1Proc( 
LPVOID lpParameter // thread data
)
{
// while(index++<1000)
// cout<<"thread 1 is running"<<endl;
while(TRUE)
{
WaitForSingleObject(hMutex,INFINITE);//请求互斥对象,用在需要被保护的代码前面,此时线程1处于未通知状态,即有信号状态
if(tickets>0)
{
Sleep(1);
cout<<"thread 1 sell ticket:"<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);//释放互斥对象,使其处于通知状态,即无信号状态
}

return 0;
}



//线程2实现代码
DWORD WINAPI Fun2Proc( 
LPVOID lpParameter // thread data
)
{
while(TRUE)
{
WaitForSingleObject(hMutex,INFINITE);//请求互斥对象,用在需要被保护的代码前面,此时线程2处于通知状态,即有信号状态
if(tickets>0)
{
Sleep(1);
cout<<"thread 2 sell ticket:"<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);//释放互斥对象,使其处于通知状态,即无信号状态
}

return 0;
}



/*
互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。
互斥对象包含一个使用数量,一个线程ID和一个计数器。(哪个线程拥有该互斥对象,就应该由哪个线程释放该互斥对象,其它线程只能释放本线程的互斥对象,
因为当一个线程拥有互斥对象的时候,互斥对象就为该线程绑定一个ID,不同线程的ID号不同,所以一个线程不能释放其它线程的互斥对象)
ID用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。(在一个线程中,调用N次互斥对象就应该相应的调用N次ReleaseMutex(hMutex),使互斥对象的计数器减1)
在一个线程中,如果在线程结束之前没有调用ReleaseMutex(hMutex),操作系统会在线程结束之后将互斥对象的ID置为0,计数器置为0,这样其它进程就可请求到该互斥对象了,为了养成良好的编程习惯还是得调用ReleaseMutex(hMutex)释放互斥对象。

*/

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在多任务操作系统环境下,进程和线程的同步控制是多线程和多进程编程的一个重点。其中,线程同步是指多个线程在执行过程中需要访问共享资源时,保证每个线程都能按照一定的顺序访问共享资源,避免出现数据不一致或者其他问题。常见的线程同步方式包括临界区、互斥量、信号量等。 临界区是线程同步的一种方式,即它在同一时刻只允许一个线程进入,其他线程只能等待。在进入临界区之前,需要获取一个锁,执行完临界区代码后再释放锁。这样可以保证在同一时刻只有一个线程在执行临界区代码,避免出现数据竞争等问题。 下面是一个示例代码,其中包括两个线程一个线程一个线程,它们共享一个数组A。写线程对数组进行10次写操作,每次写操作对A的每个元素赋一个相同的值;读线程对数组进行10次读操作,每次读操作输出A中所有元素的值。 ``` #include <stdio.h> #include <pthread.h> #define THREAD_NUM 2 #define ARRAY_SIZE 10 int A[ARRAY_SIZE]; pthread_mutex_t mutex; void *write_thread(void *arg) { int i, j; for (i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); for (j = 0; j < ARRAY_SIZE; j++) { A[j] = i; } pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } void *read_thread(void *arg) { int i, j; for (i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); for (j = 0; j < ARRAY_SIZE; j++) { printf("%d ", A[j]); } printf("\n"); pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } int main() { pthread_t threads[THREAD_NUM]; pthread_mutex_init(&mutex, NULL); pthread_create(&threads[0], NULL, write_thread, NULL); pthread_create(&threads[1], NULL, read_thread, NULL); pthread_join(threads[0], NULL); pthread_join(threads[1], NULL); pthread_mutex_destroy(&mutex); return 0; } ``` 运行结果可能会出现数据不一致的情况,因为读线程和写线程没有进行同步。为了解决这个问题,可以使用互斥量来进行同步。修改后的代码如下: ``` #include <stdio.h> #include <pthread.h> #define THREAD_NUM 2 #define ARRAY_SIZE 10 int A[ARRAY_SIZE]; pthread_mutex_t mutex; void *write_thread(void *arg) { int i, j; for (i = 0; i < 10; i++) { for (j = 0; j < ARRAY_SIZE; j++) { pthread_mutex_lock(&mutex); A[j] = i; pthread_mutex_unlock(&mutex); } } pthread_exit(NULL); } void *read_thread(void *arg) { int i, j; for (i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); for (j = 0; j < ARRAY_SIZE; j++) { printf("%d ", A[j]); } printf("\n"); pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } int main() { pthread_t threads[THREAD_NUM]; pthread_mutex_init(&mutex, NULL); pthread_create(&threads[0], NULL, write_thread, NULL); pthread_create(&threads[1], NULL, read_thread, NULL); pthread_join(threads[0], NULL); pthread_join(threads[1], NULL); pthread_mutex_destroy(&mutex); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值