【发布时间】:2017-05-10 23:39:17
【问题描述】:
我正在编写一个多线程应用程序,它读取文件并在线程内存中的块中查找单词。
如果一个线程首先找到它,则需要异步关闭其他寻找该单词的线程。
问题是当找到一个单词并且正在关闭其他线程时,程序不会终止(10 次执行中有 6 次)。我在 gdb 中检查了一个线程没有退出。即使我不打电话给waitforthreads(n_threads),也会发生这种情况。
// [...]
FILE* f;
pthread_mutex_t mutex;
pthread_t* threads;
int n_threads;
int allread;
// [...]
int main(int argc, char* argv[]) {
// [...]
threads = (pthread_t*) calloc(n_threads, sizeof(pthread_t));
pthread_mutex_init(&mutex, NULL);
runthreads(f, word, n_threads, n_records);
waitforthreads(n_threads);
pthread_mutex_destroy(&mutex);
// [...]
}
void runthreads(FILE* f, char* w, int n_threads, int n_records) {
struct targs_t args = {w, n_records};
for (int i=0; i<n_threads; i++)
pthread_create(&threads[i], NULL, findword, (void*) &args);
}
void waitforthreads(int N) {
for (int i=0; i<N; i++)
if(pthread_join(threads[i], NULL))
exit_(6);
}
void* findword(void* arg) {
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
struct targs_t* args = (struct targs_t*) arg;
int max_length = args->n_records * sizeof(record_t);
record_t* records = malloc(max_length);
int found = 0;
while (!allread && !found) {
pthread_mutex_lock(&mutex);
// allread is being set in the function below
// if the whole file has been read
readRecords((char*) records, args->n_records, f);
pthread_mutex_unlock(&mutex);
for (int i=0; i<args->n_records; i++)
if (strlen(records[i].text) == 0) break;
else if (strstr(records[i].text, args->word) != NULL) {
notifyfound(pthread_self(), records[i].id);
found = 1;
break;
}
}
free(records);
return NULL;
}
void notifyfound(pthread_t tid, int id) {
printf("Found: %d (%ld)\n", id, (long) tid);
for (int i=0; i<n_threads; i++)
if (threads[i] && !pthread_equal(threads[i], tid)) {
printf(" closing %ld\n", (long) threads[i]);
pthread_cancel(threads[i]);
}
printf(" finished closing\n");
}
【问题讨论】:
-
你从来没有为
threads分配内存。 -
@Barbar 很抱歉没有发布代码的全部相关部分。我实际上已经分配了内存。
-
您正在阅读由互斥锁保护的代码之外的
allread和found。 -
当这个线程找到匹配时,你在哪里停止其他线程?
-
假设线程在
runthreads()完成启动所有线程之前找到了单词。notifyfound()中的循环只会取消已经启动的线程,不会取消之后启动的线程。
标签: c multithreading pthreads