我编了一个多线程程序:
结构大概如下:
DWORD WINAPI thread1(LPVOID pParam){
while(1){
操作.......
fp=fopen("1","rb"); //打开文件1,这里有时候会阻塞
操作.....
fclose(fp);
操作......
thread1 = CreateThread(NULL, 0 ,thread2,(LPVOID)pthis,0,&tid);
res = Valid_ID(ID_Des); //调用一个函数
if(res==0){ //函数返回如果是0,终止线程2
TerminateThread(thread2,0);
}
}DWORD WINAPI thread2(LPVOID pParam){
操作.....
fp=fopen("2","rb"); //打开文件2
fread(&a,1,1,fp);
fclose(fp);
操作.....
}
我现在的问题是,如果调用的函数返回不是0,那么就没有终止线程2,此时不断的循环调用线程1中的fopen()没有任何问题。但是如果调用的函数返回0,那么会终止线程2,此时线程1中的fopen()有时候会阻塞,即程序运行到fopen()的时候不在向下运行。
这是怎么回事???大虾们指点一下!
结构大概如下:
DWORD WINAPI thread1(LPVOID pParam){
while(1){
操作.......
fp=fopen("1","rb"); //打开文件1,这里有时候会阻塞
操作.....
fclose(fp);
操作......
thread1 = CreateThread(NULL, 0 ,thread2,(LPVOID)pthis,0,&tid);
res = Valid_ID(ID_Des); //调用一个函数
if(res==0){ //函数返回如果是0,终止线程2
TerminateThread(thread2,0);
}
}DWORD WINAPI thread2(LPVOID pParam){
操作.....
fp=fopen("2","rb"); //打开文件2
fread(&a,1,1,fp);
fclose(fp);
操作.....
}
我现在的问题是,如果调用的函数返回不是0,那么就没有终止线程2,此时不断的循环调用线程1中的fopen()没有任何问题。但是如果调用的函数返回0,那么会终止线程2,此时线程1中的fopen()有时候会阻塞,即程序运行到fopen()的时候不在向下运行。
这是怎么回事???大虾们指点一下!
解决方案 »
- c++简易版DirectUI界面库构建详解 [ 17课全 ]
- comm 命令
- VC2008中如何锁定停靠窗CDockableBar的大小
- 求助:关于字体显示
- 如何在菜单中调用BCG的VIEW类?
- 这样的按钮容器,可以放在窗口上,但它是下陷的,类似编辑框(也就是比窗口平面低),可以改变底色,能够在它上面放置按钮(或者自画),
- 在线等!!rm格式文件转为dat格式?急!!
- --------有关连接点的问题,为什么我的事件接收器不能接收到事件?----------
- 一个不理解的....
- 头疼,C/S模式服务器软件中的Socket断言出错。高手都来看看
- 紧急求助:UNICODE状态下无语法错误,却不能实现拷贝功能,望高手支招!看看是什么原因?
- 控制台程序中如何使用CreatFile、WrtieFile、ReadFile
按你说的是否能实现在thread1中终止thread2线程?
DWORD WINAPI thread1(){
FILE *fp1;
char type;
short version; unsigned long length;
if((fp1=fopen("CRL","rb"))==NULL){
printf("不能打开文件,请确认\"CRL\"文件是否存在\n");
return 0;
}
fread(&type,1,1,fp1);
fread(&version,2,1,fp1);
fread(&length,4,1,fp1);
printf"1*****************************************************************\n");
printf("1类型:%d 版本号:%d 列表长度:%ld\n",type,version,length);
printf("\n1显示完毕!\n") ;
printf("1****************************************************************\n");
fclose(fp1);
return 1;
}
int main( void ) {
FILE *fp;
char type;
short version;
unsigned long length;
HANDLE handle1;
int i;
handle1=CreateThread(NULL,0,thread1,NULL,0,NULL);
for (i=0;i<=9000;i++){ //调整循环次数可以提高fopen阻塞情况出现的频率
;
}
TerminateThread(handle1,0 );
if((fp=fopen("CRL","rb"))==NULL){
printf("不能打开文件,请确认\"CRL\"文件是否存在\n");
return 0;
}
fread(&type,1,1,fp);
fread(&version,2,1,fp);
fread(&length,4,1,fp);
printf("*****************************************************************\n");
printf("类型:%d 版本号:%d 列表长度:%ld\n",type,version,length);
printf("\n显示完毕!\n") ;
printf("*****************************************************************\n");
fclose(fp);
return 1
}
大家要多运行几次才能发现fopen被阻塞的情况。
HANDLE g_hThread1 = NULL;
DWORD WINAPI thread1(){
FILE *fp1;
char type;
short version; if(g_bStop)
return 0;
unsigned long length;
if((fp1=fopen("CRL","rb"))==NULL){
printf("不能打开文件,请确认\"CRL\"文件是否存在\n");
return 0;
}
if(g_bStop)
{
fclose(fp1);
return 0;
} fread(&type,1,1,fp1);
fread(&version,2,1,fp1);
fread(&length,4,1,fp1);
printf"1*****************************************************************\n");
printf("1类型:%d 版本号:%d 列表长度:%ld\n",type,version,length);
printf("\n1显示完毕!\n") ;
printf("1****************************************************************\n");
fclose(fp1);
return 1;
}
int main( void ) {
FILE *fp;
char type;
short version;
unsigned long length;
// HANDLE handle1;
int i;
g_bStop = FALSE;
g_hThread1=CreateThread(NULL,0,thread1,NULL,0,NULL);
for (i=0;i<=9000;i++){ //调整循环次数可以提高fopen阻塞情况出现的频率
;
}
g_bStop = TRUE;
WaitForSingleObject(g_hThread1, INFINITE);
if((fp=fopen("CRL","rb"))==NULL){
printf("不能打开文件,请确认\"CRL\"文件是否存在\n");
return 0;
}
fread(&type,1,1,fp);
fread(&version,2,1,fp);
fread(&length,4,1,fp);
printf("*****************************************************************\n");
printf("类型:%d 版本号:%d 列表长度:%ld\n",type,version,length);
printf("\n显示完毕!\n") ;
printf("*****************************************************************\n");
fclose(fp);
return 1
}
1.我想知道为什么使用TerminateThread()会造成fopen()阻塞,我查看帮助文件,上面只说明了
当线程中调用了dll或有critical section或在执行 kernel32 calls 时,调用TerminateThread()会出现问题,可为什么会导致fopen()调用阻塞呢?
2.经过改动是可以实现终止线程2,可是由于要判断g_bstop的状态,就要不断的使用if(g_bStop)语句来进行判断,在我原来的程序里线程2比较长,这就意味着我要多次调用if(g_bStop)来检查g_bstop的状态(估计要调用10次以上,以便及时发现终止线程2的信息),这样做总感觉比较麻烦,好像没有使用TerminateThread()来的简单,有没有更好的办法来终止线程2?
还有使用线程的时候不要用ExitThread或TeminateThread之类的函数,C运行期库会自己调用的呀.
我没看明白阻塞是啥意思?主线程或Thread1不执行了么?两个线程访问同一资源的话用互斥锁或critical section不好么?TerminateThread()会造成fopen()阻塞?我不信!~~ -____-!~
另外我之所以要调用TeminateThread,是因为我需要在某些情况下在thread2还没有完成的时候终止它
所以一般都用_beginthreadex,它与_endthreadex对应啊.用CreateThread再调用_endthreadex有些不轮不类.另外,设计良好的程序重来不用TeminateThread来终止,因为被终止的线程收不到任何通知...
{
public:
A();
~A();
}
DWORD Thread1(void)
{
A a;
Te r m i n a t e T h r e a d(0);
}
上面的线程不会调用析构函数.因为Te r m i n a t e T h r e a d
1.我想知道为什么使用TerminateThread()会造成fopen()阻塞?
这个问题到现在还没搞懂,njg_jh(糨糊)说可能产生了死锁,但是怎么就死锁了呢,就我理解,
死锁的产生一般出现在使用同步机制的情况下,可是我的程序里没有使用同步机制啊。
2.经过改动是可以实现终止线程2,可是由于要判断g_bstop的状态,就要不断的使用if(g_bStop)语句来进行判断,在我原来的程序里线程2比较长,这就意味着我要多次调用if(g_bStop)来检查g_bstop的状态(估计要调用10次以上,以便及时发现终止线程2的信息),这样做总感觉比较麻烦,好像没有使用TerminateThread()来的简单,有没有更好的办法来终止线程2?
关于“有没有更好的办法来终止线程2”这个问题大家还没有回答,是不是只能不停的判断g_bstop
的值来决定是否该结束线程2?
希望大家能帮助我搞清楚上面2个问题,谢谢!
while(1){
操作.......
fp=fopen("1","rb"); //打开文件1,这里有时候会阻塞
操作.....
fclose(fp);
操作......
thread1 = CreateThread(NULL, 0 ,thread2,(LPVOID)pthis,0,&tid);
res = Valid_ID(ID_Des); //调用一个函数
if(res==0){ //函数返回如果是0,终止线程2
TerminateThread(thread2,0);
}
}DWORD WINAPI thread2(LPVOID pParam){
操作.....
fp=fopen("2","rb"); //打开文件2
fread(&a,1,1,fp);
fclose(fp);
操作.....
}
===============================================================================
主要下面代码:
res = Valid_ID(ID_Des); //调用一个函数
if(res==0){ //函数返回如果是0,终止线程2
TerminateThread(thread2,0);
上面不是好的代码,绝对应该避免。
最好是重新设计吧...比如让thread执行Valid_ID.
可以想象如果res是全局变量(或者是内核对象),不可能thread2的每条语句都执行检查res(或者是内核对象)标志,如果res = 0,那么thread2 return;
非要这么做就用 TerminateThread(thread2,0);吧
把hThread = (HANDLE)_beginthreadex(NULL,0,thread1,NULL,0,NULL);前面操作文件
的语句移到TerminateThread后面也同样没有异常.
所以TerminateThread造成阻塞是不对的呀...#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <process.h>#define FILEPATH "c:\\test.txt"
#define BUFSIZE 32unsigned int _stdcall thread1(void * pparam)
{
FILE *fp;
char cont[BUFSIZE] = "这是子进程写入的.\r\n"; printf("子线程开始操作文件.\n");
fp = fopen(FILEPATH,"a");
if(fp == NULL){
printf("子线程打开文件发生错误.\n");
return(-1);
} if(fwrite(cont,strlen(cont),1,fp) != 1){
printf("子线程写文件发生错误.\n");
return(-1);
}
if(fclose(fp) == -1){
printf("子线程关闭文件发生错误.\n");
return(-1);
}
printf("子线程关闭文件.\n");
return(0);
}int _tmain(int argc, _TCHAR* argv[])
{
FILE *fp;
char cont[BUFSIZE] = "这是父进程写入的.\r\n";
HANDLE hThread; printf("主线程开始操作文件.\n");
fp = fopen(FILEPATH,"a");
if(fp == NULL){
printf("主线程打开文件发生错误.\n");
return(-1);
} if(fwrite(cont,strlen(cont),1,fp) != 1){
printf("主线程写文件发生错误.\n");
return(-1);
}
if(fclose(fp) == -1){
printf("主线程关闭文件发生错误.\n");
return(-1);
}
printf("主线程关闭文件.\n"); hThread = (HANDLE)_beginthreadex(NULL,0,thread1,NULL,0,NULL); TerminateThread(hThread,0); getchar(); return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
FILE *fp;
char cont[BUFSIZE] = "这是父进程写入的.\r\n";
HANDLE hThread;
int i; hThread = (HANDLE)_beginthreadex(NULL,0,thread1,NULL,0,NULL);
for(i=0;i<100000;i++)
;
TerminateThread(hThread,0); printf("主线程开始操作文件.\n");
fp = fopen(FILEPATH,"a");
if(fp == NULL){
printf("主线程打开文件发生错误.\n");
return(-1);
} if(fwrite(cont,strlen(cont),1,fp) != 1){
printf("主线程写文件发生错误.\n");
return(-1);
}
if(fclose(fp) == -1){
printf("主线程关闭文件发生错误.\n");
return(-1);
}
printf("主线程关闭文件.\n");
return 0;
}
hThread[1] = (HANDLE)_beginthreadex(NULL,0,thread2,0,0,NULL); hThread[0] = (HANDLE)_beginthreadex(NULL,0,thread1,0,CREATE_SUSPENDED,NULL);
SetThreadPriority(hThread[0],THREAD_PRIORITY_HIGHEST);
ResumeThread(hThread[0]);
CloseHandle(hThread[0]);