微信怎么注销实名名的遗失微信号

c语言多线程运行后为什么值会变成这样请问为什么运行下列程序后,gCount的值不为5,而是为一个莫名其妙的随机数啊?如果说是多线程影响的,那毕竟加和减在两个函数里都限定死了为次,那运算
c语言多线程运行后为什么值会变成这样
请问为什么运行下列程序后,gCount的值不为5,而是为一个莫名其妙的随机数啊?
如果说是多线程影响的,那毕竟加和减在两个函数里都限定死了为次,那运算结果应该还是为5啊?
整个运行机制到底是怎样的?
求大神解答!
volatile unsigned int gCount=5;
//gCount是全局共享变量,volatile表明不进行优化
unsigned __stdcall FirstThreadFunc(void *pArguments)
for(i=0;i&;i++)
gCount=gCount+1;
unsigned __stdcall SecondThreadFunc(void *pArguments)
for(i=0;i&;i++)
gCount=gCount-1;
int main()
HANDLE hThread[2];
unsigned threadID[2];
printf("gCount的初始值为%dn",gCount);
hThread[0]=(HANDLE)_beginthreadex(NULL,0,FirstThreadFunc,NULL,0,&threadID[0]);
hThread[1]=(HANDLE)_beginthreadex(NULL,0,SecondThreadFunc,NULL,0,&threadID[1]);
WaitForSingleObject(hThread[0],INFINITE);
WaitForSingleObject(hThread[1],INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
printf("并发修改后,gCount的值为%dn",gCount);
应该是线程安全问题。
解决方案二:
//声明关键段(临界区)
CRITICAL_SECTION
//gCount是全局共享变量,volatile表明不进行优化
volatile unsigned int gCount = 5;
unsigned __stdcall FirstThreadFunc(void *pArguments)
//进入临界区
//g_csNumber的成员OwningThread代表哪个线程
//拥有临界区,如果OwningThread为NULL,
//则当前线程进入临界区
//如果不为空并当和前线程ID
//不相等则等待
EnterCriticalSection(&g_csNumber);
for (i = 0; i&; i++)
gCount = gCount + 1;
//离开临界区
LeaveCriticalSection(&g_csNumber);
Sleep(50);
unsigned __stdcall SecondThreadFunc(void *pArguments)
//进入临界区
//g_csNumber的成员OwningThread代表哪个线程
//拥有临界区,如果OwningThread为NULL,
//则当前线程进入临界区
//如果不为空并当和前线程ID
//不相等则等待
EnterCriticalSection(&g_csNumber);
for (i = 0; i&; i++)
gCount = gCount - 1;
//离开临界区
LeaveCriticalSection(&g_csNumber);
int main()
HANDLE hThread[2];
unsigned threadID[2];
printf("gCount的初始值为%dn", gCount);
//初始化临界区
InitializeCriticalSection(&g_csNumber);
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, FirstThreadFunc, NULL, 0, &threadID[0]);
//第5个参数,0为运行状态,CREATE_SUSPENDED为挂起状态,阻塞
hThread[1] = (HANDLE)_beginthreadex(NULL, 0, SecondThreadFunc, NULL, 0, &threadID[1]); //第5个参数,0为运行状态,CREATE_SUSPENDED为挂起状态,阻塞
WaitForSingleObject(hThread[0], INFINITE);
//若为零则不等待,也就不会输出子线程函数里面的内容
WaitForSingleObject(hThread[1], INFINITE);
//若为零则不等待,也就不会输出子线程函数里面的内容
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
printf("并发修改后,gCount的值为%dn", gCount);
以上是我的代码,我加了临界区,保证线程互斥,也就是说在线程一给全局变量加的时候,保证线程二不能够对全局变量进行访问,直到线程一访问完之后,才可以,你还是没有理解多线程问题。
【云栖快讯】快速解决数据库难题,云数据库经典案例及最佳实践直播专场!阿里云数据库专家团队成员倾囊相授!赶紧报名。&&
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
RDS是一种稳定可靠、可弹性伸缩的在线数据库服务。支持MySQL、SQL Server、PostgreSQL、高...Linux下的C语言多线程编程_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Linux下的C语言多线程编程
上传于|0|0|文档简介
&&Linux下的C语言多线程编程
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩10页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢C语言多线程编程基础 - 博客频道 - CSDN.NET
进击的白嘟
分类:c语言
本文最早发表于CUIT技术网,非本人原创,转载自博客()或CUIT技术网()
我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我的程序是在Linux下写的,所以我使用了Pthread库(是不是很伤心,我知道有不少人期待的是WindowsAPI的,好吧,有机会以后再讲那个,现在先把这一系列专题写完 ^_^)
如果你用的是LINUX/UNIX/MacOSX,那么我们已经可以开始了,如果你用的是WINDOWS,那么你需要从网站上下载PTHREAD的WINDOWS开发包,所幸他非常的小。网站地址是
先来看一个基本的例子:
void* tprocess1(void* args){
cout && "tprocess1" &&
return NULL;
void* tprocess2(void* args){
cout && "tprocess2" &&
return NULL;
int main(){
pthread_t t1;
pthread_t t2;
pthread_create(&t1,NULL,tprocess1,NULL);
pthread_create(&t2,NULL,tprocess2,NULL);
pthread_join(t1,NULL);
在上面的例子中,我们首先加入了pthread.h文件包含,这是所以pthread多线程程序所必须的,接着是iostream我们进行输入输出时要用到,接着就是两个函数的定义,这和普通的函数没有什么区别,之所以写成的
void* tprocess1(void* args)
这样的形式,完全是为了迎合pthread_create函数的参数类型,你也可以不这样定义,只要在调用pthread_create创建线程的时候强制转换一下指针类型就可以了。
这两个函数将被用做线程的执行体,也就是说在两个线程里同时运行这两个函数。
现在我们来看main函数,和pthread有关的调用都在这里了。
pthread_t是线程结构,用来保存线程相关数据,你也可以理解为是线程类型,声明一个线程对象(变量)。
pthread_t t1;
pthread_t t2;
这里我们声明了两个线程变量t1,t2
pthread_create(&t1,NULL,tprocess1,NULL);
pthread_create(&t2,NULL,tprocess2,NULL);
这两句非常重要,pthread_create用来创建线程并启动,他的原型是
int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (start_routine)(void ), void * arg);
我们可以知道第一个参数是线程指针,第二参数是线程属性指针,线程属性pthread_attr_t用来指定线程优先级等属性,一般的情况下,我们没有必要修改,使用默认属性来构造线程,所以这里一般取NULL,我们也是这样做的,第三个参数是一个函数指针(函数指针?什么东西,没听说过啊?……巨晕,好嘛,你复习一下C或是C++指针那部分吧)就是线程要执行的代码,这里我们分别要执行tprocess1 tprocess2就写成了上面的样子,这里这个函数指针的类型定义是返回一个空类型指针,接收一个空类型指针参数的函数指针,如果你的函数不是这个定义,那就可以直接转化一下就可以了。
写完这两行代码,两个线程就已经执行起来了,但是如果你省略了
pthread_join(t1,NULL);
然后尝试编译运行程序的时候你会发现程序似乎什么也没干就退出了,是的,那是因为程序的主线程退出的时候操作系统会关闭应用程序使用的所有资源,包括线程……所以在main函数结束前我们得想办法让程序停下来,pthread_join方法的功能就是等待线程结束,要等的线程就是第一个参数,程序会在这个地方停下来,直到线程结束,第二个参数用来接受线程函数的返回值,是void**类型的指针,如果没有返回值,就直接设为NULL吧。
程序写好了,我们怎么编译运行它呢?
如果你使用的是Linux:
在终端里输入
g++ thread.cpp -othread -lpthread
就可以完成程序的编译及运行
如果你用的是VC:
在工程属性里加入开发包里的几个库文件
把那几个DLL文件放到你的工程路径里,也就是程序运行时候的工作路径,这个在VC6和2005里似乎不太一样,如果你不确定,那就直接放到SYSTEM32里吧。。。
下面的工作就非常简单了
点运行,提示编译,就确定,好了,结果出来了。。。
是不是感觉多线程如此的简单,短短几行代码就搞定了,我想你已经可以写出一个简单的多线程程序了吧,呵呵,其实问题没有这么简单,多线程我们还要面对线程同步的问题,我会在下一个专题里给大家讲到。
排名:千里之外
(3)(1)(5)(2)

我要回帖

更多关于 微信怎么注销实名认证 的文章

 

随机推荐