Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales
Autor
|
Tema: Problemas con Multiprocesamiento (Leído 1,007 veces)
|
|
Karman
|
Holas, estoy teniendo el siguiente problema, trabajo con gcc sobre XP con un procesador dual core amd, estoy haciendo un programa donde tengo una ventana, llamémosle X, en donde su proceso principal es x_proc()... y el problema es que dentro de dicha parte del código trabajo con una lista dinámica (pila) accediendo a ella y modificándola (rara vez), el tema es que decubrí que por el tema del doble procesador se ejecuta dicha porción de código 2 veces en paralelo osea... no dos veces lo mismo, pero si en paralelo, y me provoca fallas cuando proceso la pila, actualmente lo "solucioné" creando una copia de la lista cada vez que es llamado y trabajar con la copia (una por hilo), pero no es del todo efectivo porque provoca una sobrecarga de proceso y no tengo las modificaciones que realiza cada hilo a su lista... la pregunta sería, cual es la función para evitar que una parte del código no se ejecute en paralelo con un multiprocesador ya que probé con las clásicas "entercriticalsection" y otras más pero no tuve resultados favorables... o si no, como creen que podría hacer para poder solucionar este problema de otra forma...
S2
|
|
|
|
|
En línea
|
|
|
|
Anibal784
Desconectado
Mensajes: 762
Yo no la vote, pero me la tengo que aguantar igual
|
Que sea doble/triple/cuadruple/sixtuple/cientuple (  ) procesador no es el problema. El problema es que estás haciendo uso (aunque no lo veas) de threads. Tenés que usar funciones de sincronozación, si no me equivoco windows maneja semáforos o algo así.
|
|
|
|
|
En línea
|
El que llega sin que lo llamen, se va sin que lo echen. Vos no la votaste por eso la tenes adentro.
Lo fino no es lo tuyo, y a mi me chupa un huevo, soy argentino y no peronista, y eso es lo que realmente te molesta.
|
|
|
|
Karman
|
si... pero para este tipo de problemas windows dispone de una funcioncita: void EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); pero no sé porqué no pasa nada... se sigue ejecutando el 2º thread... cuando la inicializo me dice que está todo bien, pero no pasa nada... S2
|
|
|
|
|
En línea
|
|
|
|
|
Karman
|
acabo de probar este código: int main(int argc, wchar_t **args) { SYSTEM_INFO m_si = {0, }; GetSystemInfo(&m_si); DWORD_PTR c = m_si.dwNumberOfProcessors; m_threads = new HANDLE[c]; InitializeCriticalSectionAndSpinCount(&g_crit_sec, 0x80000400); for(DWORD_PTR i = 0; i < c; i++) { DWORD_PTR m_id = 0; DWORD_PTR m_mask = 1 << i; m_threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMain, (LPVOID)i, 0, &m_id); //SetThreadAffinityMask(m_threads[i], m_mask); wprintf(L"Creating Thread %d (0x%08x) Assigning to CPU 0x%08x\r\n", i, (LONG_PTR)m_threads[i], m_mask); } system("pause"); return 0; } DWORD_PTR WINAPI threadMain(void* p) { int m_start; EnterCriticalSection(&g_crit_sec); while(g_start<500){ m_start = g_start; g_start += 100; printf("thread: %d val %d\n",(int)p,m_start); Sleep(100); } LeaveCriticalSection(&g_crit_sec); //do something with m_start wprintf(L"g_start = %d\r\n", m_start); return 0; } y funciona perfectamente... pero en mí código no funciona... no se que hacer!!! este es mi código: EnterCriticalSection(&g_crit_sec); if(onthread) printf("No te ejecutes!!!!\n"); onthread=1; forcedEvntTable.GotoFirst(); while(!forcedEvntTable.End()){//fET.End()){// //fep=fET.Next(); fep=forcedEvntTable.Next(); if(uMsg==WM_SIZE) printf("uMsg -> Sizing... %X %X\n",fep,&CriticalForcedET); if(fep->GetEventCode()==WM_SIZE&&uMsg==WM_SIZE) printf("fep->GetEventCode() -> Sizing... %X\n",fep); if(fep->GetEventCode()==uMsg){ ctrlId=fep->GetControlId(); if(!ctrlId||(ctrlId&&ctrlId==(LOWORD(wParam)))){ pWClass=(xgWindow*)(fep->GetPClass()); if(pWClass){ pClassfun=(pClassWndFunc)(fep->GetClassFunction()); bRet=(pWClass->*pClassfun)((xgVoid*)this,wParam,lParam); } } } } onthread=0; LeaveCriticalSection(&g_crit_sec); la línea: printf("No te ejecutes!!!!\n"); aparece en pantalla! que estará mal??? PD: Acabo de probar con Mutex y tampoco funciona!!! Help!!! S2
|
|
|
|
« Última modificación: 14 Noviembre 2008, 14:09 por Karman »
|
En línea
|
|
|
|
|
Eternal Idol
|
Sin ver el codigo completo es dificil imaginarse el problema. Eso si, en cuanto un hilo libera la sección crita otro que este esperando la adquiere y continua su ejecucion, el punto justamente es que estos se queden esperando en lugar de ejecutarse al mismo tiempo que el que adquirio la sección critica. EnterCriticalSection The EnterCriticalSection function waits for ownership of the specified critical section object. The function returns when the calling thread is granted ownership. Si tenes varios hilos que acceden a esa lista entonces con adquirir la sección critica justo antes de acceder a la lista y liberarla justo despues de terminar de usarla no deberias tener ningun problema ... pseudo: EnterCriticalSection { UseList } LeaveCriticalSection
|
|
|
|
« Última modificación: 15 Noviembre 2008, 21:07 por Eternal Idol N&P »
|
En línea
|
 La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste. Juan Domingo Perón
|
|
|
|
Karman
|
si... entiendo lo que hace la función y creo (he llegado a la conclusión) que lo que pasa es que pasa de largo para evitar un deadlock... estuve investigando estos dos mensajes y al parecer ambos se ejecutan en forma secuencial (1->2;2->1) y como yo bloqueo en el intervalo el sistema lo detecta como deadlook e ignora la sección crítica, en realidad esto no está probado de ninguna forma, es la única explicación que le encontré al problema, de todas formas ya encaré el problema desde otro punto de vista (que tampoco estoy seguro que sea la correcta) pero bueno... (en realidad con muchos cores es probable que el código falle, se me está complicando mucho con el multiprocesamiento real...)... por ahora lo voy a dejar de la nueva forma pero en un futuro analizaré el problema más en profundidad...
S2
|
|
|
|
|
En línea
|
|
|
|
|
Eternal Idol
|
Para hacerla corta: no. Es lo que tiene que pasar, el hilo tiene que quedar bloqueado hasta que se libere la sección critica y Windows no evita deadlocks, pero depuralo mejor para verlo por vos mismo.
|
|
|
|
« Última modificación: 15 Noviembre 2008, 23:02 por Eternal Idol N&P »
|
En línea
|
 La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste. Juan Domingo Perón
|
|
|
|
Karman
|
[edited]
S2
|
|
|
|
« Última modificación: 7 Enero 2012, 10:37 por Karman »
|
En línea
|
|
|
|
|
Karman
|
ya entendí lo que pasa... lo leí en la pag de msdn pero lo logré entender hasta que me respondieron esto en otro foro: Lo que creo que te está ocurriendo es que el codigo que está protegido por las secciones criticas está generando otro mensaje por lo que se llama al procedimiento de ventana de nuevo.
Las secciones criticas están diseñadas para sincronizar distintos hilos de un mismo proceso. Cuando un hilo entra en una sección critica se convierte en el dueño (owner) de esa sección hasta que sale de ella. Si el hilo "owner" de la sección trata de entrar de nuevo en ella, se le permite incrementando un contador en la sección critica, la sección queda liberada cuando este contador es cero.
En tu caso el mismo hilo es el que entra dos veces en el procedimiento de ventana por lo que no es bloqueado. Fijate que si fuese bloqueado tendrias un "dead lock" y el hilo quedaría susendido indefinidamente.
Lo que tienes en este caso particular no es un problema de sincronización sino de control de flujo del programa. El mismo hilo llama al procedimiento de ventana dentro del procedimiento de ventana. Tendrás que controlar cuando ocurra este caso para tratarlo de manera especial.
S2
|
|
|
|
|
En línea
|
|
|
|
|
Karman
|
[edited]
S2
|
|
|
|
« Última modificación: 7 Enero 2012, 10:37 por Karman »
|
En línea
|
|
|
|
|
Eternal Idol
|
Si, las secciones criticas se pueden adquirir recursivamente, solo los otros hilos se bloquean a esperar: After a thread has ownership of a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns. PD. No te fijaste cual era el TID mientras depurabas 
|
|
|
|
|
En línea
|
 La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste. Juan Domingo Perón
|
|
|
|
Karman
|
si... eso lo leí... pero como dijiste no verifiqué el TID en ningún momento, estaba convencido que era otro hijo... je
S2
|
|
|
|
|
En línea
|
|
|
|
|
|