
Původně odeslal
Eagle
Uff, mám pocit, že jedině Fox!MURDER tady ví, o co kráčí.
Zas me prilis neprecenuj. S threadama mam zkusenosti jen minimalni (v C a par skriptovacich jazycich - napr. perl) a hru jsem taky zadnou nenapsal. Spis se na to snazim koukat 'selskym rozumem' a vnest do toho trochu vlastni invence.
Zrovna ted mi vrta hlavou jak by byly realizovatelny ty transakce (hlavne transakcni izolace) na pametovy urovni.
THX: vis ten problem s tema zamkama je trosku jinej. ono totiz nepotrebujes zamky jen pri zapisu. pokud mas scenar takovej ze mas napr. dva thready, ktery posouvaj bod po obrazovce, muze nastat nasledujici situace
Kód:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int a=0;
int b=0;
pthread_mutex_t mut_a = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mut_b = PTHREAD_MUTEX_INITIALIZER;
void *f_thread1(void *);
void *f_thread2(void *);
int main(void)
{
pthread_t thread1, thread2;
int iret1, iret2;
int i1=1,i2=2;
iret1 = pthread_create( &thread1, NULL, f_thread1, (void*) i1 );
iret2 = pthread_create( &thread2, NULL, f_thread2, (void*) i2 ) ;
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("a = %d\n",a);
printf("b = %d\n",b);
exit(0);
}
void *f_thread1(void *q){
int x=0;
for(x=0;x<65535;x++)
{
int temp1, temp2;
{
#ifdef WHOLELOCK
pthread_mutex_lock(&mut_a);
pthread_mutex_lock(&mut_b);
#endif
temp1=a+1;
temp2=b+1;
#ifndef WHOLELOCK
pthread_mutex_lock( &mut_b);
#endif
b=temp2;
#ifndef WHOLELOCK
pthread_mutex_unlock(&mut_b);
pthread_mutex_lock(&mut_a);
#endif
a=temp1;
#ifndef WHOLELOCK
pthread_mutex_unlock(&mut_a);
#endif
#ifdef WHOLELOCK
pthread_mutex_unlock(&mut_a);
pthread_mutex_unlock(&mut_b);
#endif
}
}
}
void *f_thread2(void *q){
int x=0;
for(x=0;x<65535;x++)
{
int temp1, temp2;
{
#ifdef WHOLELOCK
pthread_mutex_lock(&mut_a);
pthread_mutex_lock(&mut_b);
#endif
temp1=a-1;
temp2=b-1;
#ifndef WHOLELOCK
pthread_mutex_lock( &mut_b);
#endif
b=temp2;
#ifndef WHOLELOCK
pthread_mutex_unlock(&mut_b);
pthread_mutex_lock(&mut_a);
#endif
a=temp1;
#ifndef WHOLELOCK
pthread_mutex_unlock(&mut_a);
#endif
#ifdef WHOLELOCK
pthread_mutex_unlock(&mut_a);
pthread_mutex_unlock(&mut_b);
#endif
}
}
}
Kód:
livecd ~ # gcc -pthread threadtest.c -DWHOLELOCK -o tt-wholelock
livecd ~ # gcc -pthread threadtest.c -o tt-nowholelock
livecd ~ # ./tt-nowholelock
a = 429
b = 702
livecd ~ # ./tt-wholelock
a = 0
b = 0
livecd ~ # ./tt-wholelock
a = 0
b = 0
livecd ~ # ./tt-wholelock
a = 0
b = 0
livecd ~ # ./tt-wholelock
a = 0
b = 0
livecd ~ # ./tt-wholelock
a = 0
b = 0
livecd ~ # ./tt-nowholelock
a = 181
b = 73
livecd ~ # ./tt-nowholelock
a = 340
b = -61
livecd ~ # ./tt-nowholelock
a = -4862
b = 333
livecd ~ # ./tt-nowholelock
a = 588
b = 257
livecd ~ #
tj. jeden thread posouva ten bod (klidne to muze bejt v pripade 3D treba kvadr, nebo neco jinyho) o 1 doprava a o 1 nahoru, druhej posouva bod o 1 doleva a o 1 dolu. kazdej z nich to udela 65536krat. tj. bod by mel ve vysledku skoncit na miste, kde zacal (pravej dolni roh napr.) jenze, kdyz zamykam jen pri zapisu, ejhle ... ono to skonci na uplne nepredvidanym miste.
a jeste dodam, ze to samozrejme dosti podobne kravi i na singlecore
(testuju na C2D E6300 a CeleronuD 325, oboje Gentoo s nptl a gcc 4.1)
kdyby nekdo mel problem s pochopenim toho C kodu, tak dejte vedet, ja to vysvetlim...
jooo a vim ze by to asi slo napsat jednodusejs a prehlednejs, ale a) jsem prase, b) nemam cas si s tim tak moc hrat