Windows 多线程编程 C语言

多线程编程,基于Windows,语言是C语言。

在<windows.h>中包含多线程的相关函数等,无需再次下载库或者文件。

#include<windows.h>
#include<iostream>
#include <stdio.h>
using namespace std;

int number = -1;	//定义全局变量
CRITICAL_SECTION Critical;//定义临界区句柄
int a[4][4]={8,7,6,5,4,3,2,1,18,7,16,15,14,13,21,11};
void print(int *a,int size){
	for (int i = 0 ;i < size; i++){
		printf("%d ",a[i]);
		a[i] = a[i]+1;
	}
}
unsigned long __stdcall ThreadProc1(void* lp) {
	EnterCriticalSection(&Critical);
	printf("thread %d : %d\n",number,number);
	++number;
	int numTmp=number;
	Sleep(100);
	LeaveCriticalSection(&Critical);		
	print(a[numTmp],4);
	return 0;
}

int main() {
	
	InitializeCriticalSection(&Critical);	//初始化临界区对象
	for(int i = 0;i < 4;i++){
		HANDLE Thread;
 		DWORD dwThreadId;
 		Thread=::CreateThread
  			(NULL,0,ThreadProc1,NULL,0,&dwThreadId);
		printf("The new thread ID is : %d \n",dwThreadId);
 		::WaitForSingleObject(Thread,INFINITE);
 		::CloseHandle(Thread);
	}
	//Sleep(10*1000);
	printf("\nhello begin\n");
	for(int i = 0;i < 4; i++){
		for(int j = 0;j < 4;j++){
			printf("%d ",a[i][j]);
		}
		printf("\n");
	}
		
	printf("hello end\n");
    return 0;
}

上面的代码,试着删除::WaitForSingleObject(Thread,INFINITE);语句后,再次运行,看结果(多线程是异步的,利用该语句,强制要求线程运行完成后再返回)。如果不对线程进行同步处理,会导致后续读取前面并行线程产生的变量值是错误值(因为前面的线程可能并没有全部按照既定规则更新所有变量的值)。

下面举一例子,要求使用两个线程,对一个变量number进行加1操作,加到100即停止,number的初始值是1.显然,我们要用到信号量互斥机制,或者类似机制,保证同一时刻只能有一个进程对number进行写操作,但是,请注意,阻塞只是将线程阻塞了,保证的只是该时刻只有一个线程有写权限,被阻塞的线程在下一时刻仍有写的权限,具体来说,创建的两个线程thread1和thread2,如果在thread2正在将number加到100,此时另一个线程thread1必被阻塞,无法对number进行写操作,但是当线程thread2写完成后,线程thread1立刻解除阻塞,拥有对number的写权限,自然将number再次加一,number变为101,可见单纯设置信号量等无法实现多线程下number准确加到某一定值,对此,可以在每次获得写权限时,在写操作之前再次进行number范围判断。

下面的代码,目的是将number加到MAX_NUMBER即可,由于是两个线程并行,总会多加一个1(若是10个线程并行,则会多加9,原因同理,当某一个线程将number的值加到MAX_NUMBER之后,其他9个线程被阻塞,但是都有写权限,又在写之前并没有number值的范围判断,导致每个线程都再次对number加1)。

#include<windows.h>
#include<iostream>
#include <stdio.h>
using namespace std;
#define MAX_NUMBER 10000000
CRITICAL_SECTION Critical;//定义临界区句柄
int number = 1;

unsigned long __stdcall ThreadProc1(void* lp) {
	while (number < MAX_NUMBER) {
		if (number < MAX_NUMBER)
			EnterCriticalSection(&Critical);
		//cout << "thread 1 :"<<number << endl;
		++number;
		//Sleep(100);
		LeaveCriticalSection(&Critical);
	}

	return 0;
}

unsigned long __stdcall ThreadProc2(void* lp) {
	while (number < MAX_NUMBER) {
		if (number < MAX_NUMBER)
			EnterCriticalSection(&Critical);
		//cout << "thread 2 :"<<number << endl;
		++number;
		//Sleep(100);
		LeaveCriticalSection(&Critical);
	}

	return 0;
}

int main() {
	
	InitializeCriticalSection(&Critical);	//初始化临界区对象
	//CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	//CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
	HANDLE ThreadOne[2];
    DWORD dwThreadIdOne;
    ThreadOne[0] = ::CreateThread(NULL, 0, ThreadProc1, NULL, 0, &dwThreadIdOne);
    printf("\n\nThe new thread ID is : %d \n", dwThreadIdOne);
    
    //::CloseHandle(ThreadOne);

    //HANDLE ThreadTwo;
    DWORD dwThreadIdTwo;
    ThreadOne[2] = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, &dwThreadIdTwo);
    printf("The new thread ID is : %d \n", dwThreadIdTwo);
    //::WaitForSingleObject(ThreadTwo, INFINITE);
    //::CloseHandle(ThreadTwo);    
	
	//Sleep(10*1000);

	for(int i = 0 ;i < 2;i++)
		::WaitForSingleObject(ThreadOne[i], INFINITE);
	
	for(int i = 0;i < 2;i++)
		::CloseHandle(ThreadOne[i]);
	printf("\nhello start\n");
	printf("number: %d\n",number);printf("number: %d\n",number);printf("number: %d\n",number);printf("number: %d\n",number);
    return 0;
}

写之前添加范围判断语句

#include<windows.h>
#include<iostream>
#include <stdio.h>
using namespace std;
#define MAX_NUMBER 10000000
CRITICAL_SECTION Critical;//定义临界区句柄
int number = 1;

unsigned long __stdcall ThreadProc1(void* lp) {
	while (number < MAX_NUMBER) {
		if (number < MAX_NUMBER)
			EnterCriticalSection(&Critical);
		//cout << "thread 1 :"<<number << endl;
		if (number < MAX_NUMBER) ++number;
		//Sleep(100);
		LeaveCriticalSection(&Critical);
	}

	return 0;
}

unsigned long __stdcall ThreadProc2(void* lp) {
	while (number < MAX_NUMBER) {
		if (number < MAX_NUMBER)
			EnterCriticalSection(&Critical);
		//cout << "thread 2 :"<<number << endl;
		if (number < MAX_NUMBER) ++number;
		//Sleep(100);
		LeaveCriticalSection(&Critical);
	}

	return 0;
}

int main() {
	
	InitializeCriticalSection(&Critical);	//初始化临界区对象
	//CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	//CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
	HANDLE ThreadOne[2];
    DWORD dwThreadIdOne;
    ThreadOne[0] = ::CreateThread(NULL, 0, ThreadProc1, NULL, 0, &dwThreadIdOne);
    printf("\n\nThe new thread ID is : %d \n", dwThreadIdOne);
    
    //::CloseHandle(ThreadOne);

    //HANDLE ThreadTwo;
    DWORD dwThreadIdTwo;
    ThreadOne[2] = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, &dwThreadIdTwo);
    printf("The new thread ID is : %d \n", dwThreadIdTwo);
    //::WaitForSingleObject(ThreadTwo, INFINITE);
    //::CloseHandle(ThreadTwo);    
	
	//Sleep(10*1000);

	for(int i = 0 ;i < 2;i++)
		::WaitForSingleObject(ThreadOne[i], INFINITE);
	
	for(int i = 0;i < 2;i++)
		::CloseHandle(ThreadOne[i]);
	printf("\nhello start\n");
	printf("number: %d\n",number);printf("number: %d\n",number);printf("number: %d\n",number);printf("number: %d\n",number);
    return 0;
}

上述代码采用的是临界区句柄进行互斥判断,在使用信号量进行互斥控制时,发现意图是使用多线程,但实际上只用首先被创建的线程在进行工作,其他线程均为进行工作,待定。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值