【发布时间】:2020-12-29 08:18:00
【问题描述】:
为什么在这种情况下 fork 比线程更好?对于 139 mb (rockyou.txt) 的文件,fork 是 0.5 秒,对于相同的文件和文件末尾的相同单词,使用线程是 3 秒(使用时钟 () 和普通秒表测量,线程需要更长的时间比叉子)
该程序读取单词表的每一行,对其进行哈希处理并与摘要进行比较。
这个是带叉子的
void wordlistFork(char digest[], char hashtype[], FILE *wordlist,int numberOfFork){
int i;
clock_t t;
fseek(wordlist, 0L, SEEK_END);
long fileLength = ftell(wordlist);
fseek(wordlist, 0L, SEEK_SET);
for(i=0;i<numberOfFork;i++){
int pid = fork();
if(pid==0){
char line[512];
long initialOffset = correctOffset(lengthOfFile*i/numberOfFork,wordlist);
long finalOffset = correctOffset(lengthOfFile*(i+1)/numberOfFork,wordlist);
fseek(wordlist, initialOffset, SEEK_SET);
t = clock();
while (initialOffset < finalOffset) {
fscanf(wordlist,"%s\n",line);
char tempLine[512] = {0};
strncpy(tempLine,line,strlen(line));
if (strcmp(hash(tempLine,hashType), digest) == 0) {
printf("Child %d: Trovato! hash %s %s -> %s\n",i, tipohash, digest, linea);
t = clock() -t;
double time_taken = ((double)t)/CLOCKS_PER_SEC;
printf("Time elapsed: %f seconds\n",time_taken);
system("killall hashcrack");
return;
}
initialOffset = ftell(wordlist);
}
printf("Child %d Found nothing.\n",i);
exit(0);
}
}
for(i=0;i<numberOfFork;i++)
wait(NULL);
}
这个是带线的
for(i=0;i<numberOfThreads;i++)
pthread_create(&threads[i], NULL, (void *(*)(void *)) crack, (void *)(intptr_t) i);
for(i=0;i<numberOfThreads;i++)
pthread_join(threads[i],NULL);
void *crack(const int *args){
int threadID = (int)(intptr_t)args;
char line[512];
FILE *wordlist = fopen(Tpath,"r");
long initialOffset = correctOffset(fileLength*threadID/numberOfThreads,wordlist);
long finalOffset = correctOffset(fileLength*(threadID+1)/numberOfThreads,wordlist);
fseek(wordlist, initialOffset, SEEK_SET);
while (initialOffset < FinalOffset) {
fscanf(wordlist,"%s\n",line);
char tempLine[512] = {0};
strncpy(tempLine,line,strlen(line));
if (strcmp(hash(tempLine,hashType), Tdigest) == 0) {
printf("Thread %d: Found! hash %s %s -> %s\n",threadID, hashType, Tdigest, line);
system("killall hashcrack");
exit(0);
}
initialOffset = ftell(wordlist);
}
printf("Thread %d: found nothing.\n",threadID);
return NULL;
}
【问题讨论】:
-
提示:不要一遍又一遍地自虐地重铸同一个变量,只需声明一个具有该类型的局部变量,或者更好的是,更改参数的类型以匹配它的类型。
-
@tadman 问题是暂时的,暂时我认为我没有重铸任何东西。你说的是哪条线?
-
(struct params *)args出现的次数太多了。由于这样的习惯,这段代码最终只会变得杂乱无章。由于您受到线程函数签名的约束,因此只需声明struct params* args = args_v并将参数更改为void* v_args。瞧,不再需要重铸! -
@tadman 我也更新了代码,如果您有任何其他建议,我会全力以赴
-
您可以使用
strncpy(tempLine, line, sizeof(tempLine)-1)“修复”该问题。但是看看会发生什么:tempLine的初始化写入了 512 个零。然后副本写入几个字节的有用数据,并用 0 填充tempLine的其余部分,因为这就是strncpy所做的。结果:写了将近 1kb 的零,而您需要只写一个。这可能不是世界上最糟糕的低效率,但它肯定不会帮助您的表现。
标签: c multithreading fork