Вот эта модель №2, язык C, GCC:Olej писал(а): 2. Иметь в цикле инкремента потока логическую переменную "пора завершаться" :Вот отсюда и сложность, которая обнаружилась выше... Но она решаемая, а эффекты - очень интересные ... в разных языках программирования.Код: Выделить всё
while( finish ) count++;
Запускающий поток будет выполнять sleep() нужный интервал, после чего менять условие finish - потоки завершаться сами.
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <pthread.h>
int volatile finish = 1; // флаг завершения потока
void *RunCounter( void *res ) { // потоковая функция
long count = 0;
while( finish ) count++;
*(long*)res = count;
return NULL;
}
int main( int argc, char* argv[] ) {
int nthr = 2, // число потоков
sec = 1, // интервал выполнения
debug = 0, i;
if( argc > 1 && atoi( argv[ 1 ] ) != 0 )
nthr = atoi( argv[ 1 ] );
if( argc > 2 && atoi( argv[ 2 ] ) != 0 ) {
sec = atoi( argv[ 2 ] );
if( sec < 0 ) { // признак отладочной диагностики
sec = -sec; debug = 1;
}
}
if( debug ) printf( "число потоков %d\n", nthr );
pthread_t *tid = (pthread_t*)calloc( nthr, sizeof( pthread_t ) );
long *res = (long*)calloc( nthr, sizeof( long ) );
for( i = 0; i < nthr; i++ )
if( pthread_create( &tid[ i ], NULL, RunCounter, (void*)( res + i ) ) != 0 )
printf( "ошибка потока %d: %m", i ), exit( EXIT_FAILURE );
sleep( sec );
finish = 0;
for( i = 0; i < nthr; i++ ) pthread_join( tid[ i ], NULL );
free( tid );
if( debug )
for( i = 0; i < nthr; i++ )
printf( "%lu%s", res[ i ], ( i == nthr - 1 ? "\n" : " " ) );
double sum1 = 0, sum2 = 0, sq, md;
for( i = 0; i < nthr; i++ ) {
md = (double)res[ i ];
sum1 += md;
sum2 += md * md;
}
md = sum1 / nthr; // среднее
sq = sqrt( sum2 / nthr - md * md ); // СКО
printf( "операций %.0f : %d * %.0f [+/-%d%%]\n",
sum1, nthr, md, (int)( 100. * sq / md ) );
free( res );
return( EXIT_SUCCESS );
}
Код: Выделить всё
[Olej@modules SpeedThread.3]$ time ./CSpeed1 3 2
операций 2075162530 : 3 * 691720843 [+/-14%]
real 0m2.002s
user 0m5.877s
sys 0m0.004s
И то же самое, но с более детальным, отладочным выводом (отдельно сколько каждый поток наработал):
Код: Выделить всё
[Olej@modules SpeedThread.3]$ time ./CSpeed1 3 -3
число потоков 3
969958521 878056486 1231518592
операций 3079533599 : 3 * 1026511200 [+/-14%]
real 0m3.002s
user 0m8.786s
sys 0m0.027s