VC++;互斥问题 我只是学习C++互斥,我大部分是在MSDN上的例子。为什么我会超时?我使用Sleep()将互斥超时设置为2000ms,“假”进程设置为250ms。你可以看到它处理得很好,然后开始爆炸。。。。我知道如果我把互斥超时提高到60000毫秒,那就没问题了,但是为什么我只想在250毫秒的进程中达到这么高的超时呢?还有,为什么它会从threadid#1跳到threadid#25
谢谢! 埃里克VC++;互斥问题 我只是学习C++互斥,我大部分是在MSDN上的例子。为什么我会超时?我使用Sleep()将互斥超时设置为2000ms,“假”进程设置为250ms。你可以看到它处理得很好,然后开始爆炸。。。。我知道如果我把互斥超时提高到60000毫秒,那就没问题了,但是为什么我只想在250毫秒的进程中达到这么高的超时呢?还有,为什么它会从threadid#1跳到threadid#25,c++,multithreading,mutex,C++,Multithreading,Mutex,谢谢! 埃里克 int createMutex(char*mutexName) { #定义线程数25 句柄aThread[THREADCOUNT]; 德沃德·特莱德; int i; intid[THREADCOUNT]; //创建没有初始所有者的互斥体 ghMutex=CreateMutex( NULL,//默认安全属性 FALSE,//最初未拥有 (LPCWSTR)互斥体名称);//未命名互斥体 if(ghMutex==NULL) { 返回1; } //创建工作线程 对于(i=0;i
int createMutex(char*mutexName)
{
#定义线程数25
句柄aThread[THREADCOUNT];
德沃德·特莱德;
int i;
intid[THREADCOUNT];
//创建没有初始所有者的互斥体
ghMutex=CreateMutex(
NULL,//默认安全属性
FALSE,//最初未拥有
(LPCWSTR)互斥体名称);//未命名互斥体
if(ghMutex==NULL)
{
返回1;
}
//创建工作线程
对于(i=0;i
只需用无限或您希望的更大数字替换互斥超时
您不知道哪个线程在某个特定时间工作,因为操作系统管理它们。不要担心线程_25会更早工作。如果希望线程按创建顺序运行,则应手动管理它们。您实际上同时创建25个线程,如果每个线程都使用互斥锁约250ms,则每个线程背靠背运行,所有线程处理的总时间将为250ms*25=6250ms。记住这一点,您的一些线程肯定会在获取互斥时超时,因为您只需等待2000毫秒。实际上,它看起来像是在8个线程处理完之后,剩余的超时(这应该是意料之中的,因为250ms*8=2000ms)
至于线程#25在线程#1之后获取互斥体,我不相信在等待与获取互斥体方面有任何保证顺序。运行多次,每次运行可能会得到不同的顺序。对,我明白了。我在寻找一个我想这样做的原因。为什么我的东西不管用?如果它被设置为无限,而我有一个永远不会结束的挂起进程,会发生什么呢?因为当一个线程被互斥时,休眠250毫秒,而其他线程则愤怒地看着它。因为它得到了互斥锁并且在其他线程饥饿时休眠。当互斥被释放时,其他线程也会得到它并休眠。这种情况将持续到您的所有25个线程。实际上你的代码是有效的。只需等待线程完成它们的工作。Iridium,我的印象是,超时是针对当前持有互斥锁的线程的。您是说互斥队列中的每个线程都有自己的超时计数器吗?@kenyu73您指定的超时是调用
WaitForSingleObject
函数的线程等待获取互斥对象的最长时间。如果在该时间内未获取,它将返回WAIT\u TIMEOUT
。它对当时持有互斥对象的线程没有影响。这意味着,如果数据对时间不敏感,WaitForSingleObject的大多数实现都希望使用INFINITE。@kenyu73-这取决于用例。如果在互斥体中运行的进程有可能无限期挂起,并且永远不会释放它,那么对其他等待线程的无限期超时将导致所有开始等待互斥体的线程也永远挂起。话虽如此,在超时的情况下,通常很难确定要做什么,因此当然,将其设置为“无限”会在某种程度上简化事情。谢谢-非常有用的反馈!
int createMutex(char* mutexName)
{
#define THREADCOUNT 25
HANDLE aThread[THREADCOUNT];
DWORD ThreadID;
int i;
int ID[THREADCOUNT];
// Create a mutex with no initial owner
ghMutex = CreateMutex(
NULL, // default security attributes
FALSE, // initially not owned
(LPCWSTR)mutexName); // unnamed mutex
if (ghMutex == NULL)
{
return 1;
}
// Create worker threads
for( i=0; i < THREADCOUNT; i++ )
{
ID[i] = i +1;
aThread[i] = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) WriteToDatabase,
&ID[i], // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
if( aThread[i] == NULL )
{
return 1;
}
}
// Wait for all threads to terminate
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
// Close thread and mutex handles
for( i=0; i < THREADCOUNT; i++ ) CloseHandle(aThread[i]);
CloseHandle(ghMutex);
return 0;
}
DWORD WINAPI WriteToDatabase(int *ID){
int threadID = *ID;
char buffer[256];
int MUTEX_TIMEOUT = 2000;
int FAKE_PROCESS_TIME_DELAY = 250;
DWORD dwWaitResult;
// Request ownership of mutex.
dwWaitResult = WaitForSingleObject(
ghMutex, // handle to mutex
MUTEX_TIMEOUT); // time-out interval
sprintf(buffer, "NEW THREAD STARTED: #%d\n", threadID);
printf(buffer);
if(dwWaitResult == WAIT_OBJECT_0){
// The thread got ownership of the mutex
sprintf(buffer, "DB WRITE STATED: #%d\n", threadID);
printf(buffer);
Sleep(FAKE_PROCESS_TIME_DELAY); //simulate a long running process (db process?) which creates a WAIT_TIMEOUT
sprintf(buffer, "DB WRITE COMPLETED: #%d\n", threadID);
printf(buffer);
dwCount++;
ReleaseMutex(ghMutex);
return TRUE;
}else{
switch(dwWaitResult){
case WAIT_ABANDONED:
sprintf(buffer, "MUTEX ERROR [%s] #%d\n", "WAIT_ABANDONED", threadID);
break;
case WAIT_TIMEOUT:
sprintf(buffer, "MUTEX ERROR [%s] #%d\n", "WAIT_TIMEOUT", threadID);
break;
default:
sprintf(buffer, "MUTEX ERROR [%s] #%d\n", "UNKNOWN", threadID);
}
printf(buffer);
MutexERRORs++;
//ReleaseMutex(ghMutex);
return FALSE;
}
return TRUE;
}