Потоки производителей / потребителей не работают, используя pthread для поиска DNS - PullRequest
0 голосов
/ 29 марта 2012

Я использую проблему производителя / потребителя для создания многопоточного преобразователя 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 голосов
/ 29 марта 2012

Я предполагаю, что ваш продюсерский поток действительно работает ... в течение очень короткого промежутка времени. В вашей функции main() вы создаете поток производителя, а затем сразу после этого ваша программа завершает работу (потому что функция main возвращается. Попробуйте добавить это, прежде чем вернуть:

pthread_join(producer_tid, &return_value_p);

После того, как вы начнете создавать потребительские потоки, вам необходимо убедиться, что вы также ждете завершения всех из них, прежде чем выходить из своей программы.

...