生产者/消费者线程无法使用pthread进行DNS查找

时间:2012-03-29 01:24:53

标签: c pthreads dns consumer producer

我正在使用生产者/消费者问题来制作多线程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的新手,所以我可能错过了一些东西,但对我来说它看起来好像应该有效。

1 个答案:

答案 0 :(得分:0)

我猜你的生产者线程实际上正在运行......时间很短。在main()函数中创建生成器线程,然后立即终止程序(因为main函数返回。请在返回之前尝试添加:

pthread_join(producer_tid, &return_value_p);

一旦开始创建消费者线程,您需要确保在退出程序之前也等待所有这些线程完成。