我正在使用生产者/消费者问题来制作多线程 DNS 解析器。我在没有多线程的情况下解决了它,所以我很确定我的那部分代码可以工作。基本上,我正在创建一个生产者来编写,并且(将创建)许多消费者来阅读。目前,我正在从一个包含 IP 地址的文件中读取。我不知道为什么我的生产者线程没有运行;在让我的消费者运行之前,我需要弄清楚这是怎么回事。任何帮助都感激不尽。
这是我的代码(到目前为止):
/*
* dns_lookup.c
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "linkedlist.h"
const int BUFF_SIZE = 20;
int ip_count;
FILE *fp;
list_t *list;
pthread_mutex_t mutex;
void *do_work(char *addr)
{
struct addrinfo hints;
struct addrinfo *result;
char hbuf[NI_MAXHOST];
int rc = 0;
int count = 0;
// initialize the addrinfo struct
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
// convert the dotted-quad address to an ip address
rc = getaddrinfo(addr, NULL,&hints, &result);
if (rc != 0) {
fprintf(stderr,"getaddrinfo failed: %s\n", gai_strerror(rc));
exit(EXIT_FAILURE);
}
printf("%s -> ", addr);
rc = getnameinfo(result->ai_addr, result->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
if (count++ > 0) printf(",");
if (rc != 0) {
printf("%s", addr);
}
else {
printf("%s",hbuf);
}
result = result->ai_next;
printf("\n");
}
void *producer(void *param);
void *consumer(void *param);
void *init();
int main(int argc, char **argv[])
{
fp=fopen("access.log", "r");
list = malloc(sizeof(list_t));
list->head = NULL;
pthread_t producer_tid;
pthread_t consumer_tid;
pthread_attr_t attr;
pthread_mutex_init(&mutex, NULL);
pthread_attr_init(&attr);
pthread_create(&producer_tid, &attr, producer, NULL);
}
void *producer(void *param)
{
printf("%s", "thread created");
char line[1024];
while (!feof(fp))
{
fgets(line, sizeof line, fp);
char *tempstr = strtok(line, " ");
char *ipaddr = malloc(sizeof(char) * 50);
strncpy(ipaddr, tempstr, 20);
pthread_mutex_lock(&mutex);
add(list, ipaddr);
node_t *temp = get(list, 0);
printf("%s\n", temp->data);
pthread_mutex_unlock(&mutex);
}
}
void *consumer(void *param)
{
char *addr;
addr = get(list, 0);
do_work(addr);
}
编辑:我修复了一些代码,我认为它应该可以工作。但是,它仍然没有。
/*
* dns_lookup.c
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "linkedlist.h"
const int BUFF_SIZE = 20;
int ip_count;
FILE *fp;
list_t *list;
sem_t full;
sem_t empty;
pthread_mutex_t mutex;
void *do_work(char *addr)
{
struct addrinfo hints;
struct addrinfo *result;
char hbuf[NI_MAXHOST];
int rc = 0;
int count = 0;
// initialize the addrinfo struct
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
// convert the dotted-quad address to an ip address
rc = getaddrinfo(addr, NULL,&hints, &result);
if (rc != 0) {
fprintf(stderr,"getaddrinfo failed: %s\n", gai_strerror(rc));
exit(EXIT_FAILURE);
}
printf("%s -> ", addr);
rc = getnameinfo(result->ai_addr, result->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
if (count++ > 0) printf(",");
if (rc != 0) {
printf("%s", addr);
}
else {
printf("%s",hbuf);
}
result = result->ai_next;
printf("\n");
//exit(EXIT_SUCCESS);
}
void *producer(void *param);
void *consumer(void *param);
void *init();
void main(int argc, char **argv[])
{
fp=fopen("access.log", "r");
list = malloc(sizeof(list_t));
list->head = NULL;
int thread_count = atoi(argc);
pthread_t producer_tid;
pthread_t consumer_tid[thread_count];
pthread_attr_t attr;
//ip_count = 0;
sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFF_SIZE);
pthread_mutex_init(&mutex, NULL);
pthread_attr_init(&attr);
pthread_create(&producer_tid, NULL, producer, NULL);
int threads;
for(threads=0; threads<=thread_count; threads++)
{
pthread_create(&consumer_tid[threads], NULL, consumer, NULL);
}
pthread_join(producer_tid, NULL);
for(threads=0; threads<=thread_count; threads++)
{
pthread_join(consumer_tid[threads], NULL);
}
exit(fp);
exit(EXIT_SUCCESS);
}
void *producer(void *param)
{
printf("thread created%s");
char line[1024];
while (1)
{
sem_wait(&empty);
while (!feof(fp))
{
fgets(line, sizeof line, fp);
char *tempstr = strtok(line, " ");
char *ipaddr = malloc(sizeof(char) * 50);
strncpy(ipaddr, tempstr, 20);
pthread_mutex_lock(&mutex);
add(list, ipaddr);
node_t *temp = get(list, 0);
printf("%s\n", temp->data);
pthread_mutex_unlock(&mutex);
}
sem_post(&full);
}
}
void *consumer(void *param)
{
while(1)
{
sem_wait(&full);
pthread_mutex_lock(&mutex);
char *addr;
addr = get(list, 0);
do_work(addr);
remove_head(list);
pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
}
我没有看到任何工作。有什么建议么?
当我调试它时,我不断收到段错误。我不知道他们为什么或从哪里来;我是 pthreads 的新手,所以我可能错过了一些东西,但对我来说它看起来应该可以工作。