【发布时间】:2016-12-26 14:36:24
【问题描述】:
我正在使用 pthread 编写我的第一个 C 程序。我想为命令行 (argv) 上提供的所有(非选项)参数运行我的函数 sha1sum。
pthread_t t[256];
c = 0;
for (n = optind; n < argc; n++) {
if(pthread_create(&t[c], NULL, sha1sum, argv[n])) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
c++;
}
c = 0;
for (n = optind; n < argc; n++) {
pthread_join(t[c]);
c++;
}
当使用 2 个命令行参数(file1、file2)运行我的程序时。在成功执行 sha1sum 函数后,它有时会立即出现段错误,有时会在最后出现。
有人能指出什么是错的吗?
编辑
事实证明,程序有时仍会出现段错误。有时马上,有时在中间,有时从不:
我在下面发布整个 MCV 示例:
#include <stdio.h>
#include <getopt.h>
#include <unistd.h>
#include <locale.h>
#include <pthread.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <openssl/evp.h>
static unsigned char flag = 0;
int sha1sum(char *filename) {
FILE *f;
size_t len;
unsigned char buffer[BUFSIZ];
EVP_MD_CTX hashctx;
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
const EVP_MD *hashptr = EVP_get_digestbyname("SHA1");
f = fopen(filename, "r");
EVP_MD_CTX_init(&hashctx);
EVP_DigestInit_ex(&hashctx, hashptr, NULL);
do {
len = fread(buffer, 1, BUFSIZ, f);
EVP_DigestUpdate(&hashctx, buffer, len);
} while (len == BUFSIZ);
unsigned int outlen;
EVP_DigestFinal_ex(&hashctx, buffer, &outlen);
EVP_MD_CTX_cleanup(&hashctx);
int i;
for (i = 0; i < outlen; i++)
printf("%02x", buffer[i]);
printf("\n");
fclose(f);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
int c,n;
pthread_t t[256];
while ((c = getopt(argc, argv, "c")) != EOF) switch(c) {
case 'c':
flag |= 1;
break;
}
c = 0;
for (n = optind; n < argc; n++) {
if (pthread_create(&t[c], NULL, &sha1sum, argv[n])) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
c++;
}
c = 0;
for (n = optind; n < argc; n++) {
pthread_join(t[c], NULL);
c++;
}
return 0;
}
编辑 2
添加#include <pthread.h> 后,我现在在编译时收到以下错误/警告:
test.c: In function ‘main’:
test.c:67:9: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
In file included from test.c:9:0:
/usr/include/pthread.h:225:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘int (*)(char *)’
【问题讨论】:
-
运行单线程时是否显示相同的行为?
-
另外请提供MCV example。
-
这个 sn-p 看起来不错,除了
pthread_join需要 2 个参数(可能需要一个最小的sha1sum函数来了解更多信息)。 -
@alk - 当我只使用一个参数(一个文件)运行它时,它不会出现段错误。
-
编译器告诉你出了什么问题,你的线程函数的类型应该是
void* sha1sum(void *arg)(你可以转换成正确的类型)。我还建议您将一些 OpenSSL 的初始化(即OpenSSL_add_all_algorithms和ERR_load_crypto_strings)移出线程函数,因为它们可能不是可重入的,并且如果从多个线程并行调用可能会表现不佳。 (或者,使用线程中的pthread_once来处理这些)