// hash mining in multiple threads // fixed w12/pthread2.c # #include #include #include #include #include #include void error( const char *msg) { perror(msg); exit(1); } #define offset_basis 2166136261U #define FNV_prime 16777619U // FNV hash from http://www.isthe.com/chongo/tech/comp/fnv/ // unsigned int fnv1a( unsigned char *d, size_t n) { unsigned int hash = offset_basis; while( n--) { hash ^= *d++; hash *= FNV_prime; } return hash & 0xFFFFFF; // bottom 24 bits } unsigned int ans = 0xabcdef; // desired hash output typedef struct { // per-thread data int tn; unsigned int start, stop; } Data; #define NT 4 // number of threads Data d[NT]; void *f(void *p) { // thread worker Data *d = p; printf( "f %i %u %u\n", d->tn, d->start, d->stop); unsigned int x = d->start; while(1) { char buf[BUFSIZ]; sprintf( buf, "%08x", x); unsigned int h = fnv1a( (unsigned char *) buf, 8 ); if( h == ans) { printf( "f %i x %s ans %x\n", d->tn, buf, h); break; } if( x == d->stop) break; ++x; } printf( "f %i stop\n", d->tn); return 0; } int main( void) { setbuf( stdout, 0); int fd[2]; if( pipe(fd) < 0) perror("pipe"); dup2(fd[0],0); // connect stdin to pipe dup2(fd[1],1); // connect stdout to pipe close(fd[0]); close(fd[1]); // close unneeded descriptors unsigned int start = 0; // if NT=1 count overflows but is not used unsigned int count = (unsigned int) ((UINT_MAX+1ULL)/NT); for( int i = 0; i < NT; ++i) { d[i].tn = i; d[i].start = start; d[i].stop = (i == NT-1) ? UINT_MAX : start + (count - 1); start += count; } pthread_t t[NT]; for( int i = 0; i < NT; ++i) if( pthread_create( &t[i], 0, f, &d[i]) != 0) error( "pthread_create"); char msg[BUFSIZ]; int done = 0; while( fgets(msg,BUFSIZ,stdin)) { // read from the pipe fprintf( stderr, "%s", msg); // write to terminal if( strstr( msg, "ans") ) break; if( strstr( msg, "done") ) ++done; if( done == NT) break; } }