我正在使用生产者/消费者问题来制作多线程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的新手,所以我可能错过了一些东西,但对我来说它看起来好像应该有效。
答案 0 :(得分:0)
我猜你的生产者线程实际上正在运行......时间很短。在main()
函数中创建生成器线程,然后立即终止程序(因为main
函数返回。请在返回之前尝试添加:
pthread_join(producer_tid, &return_value_p);
一旦开始创建消费者线程,您需要确保在退出程序之前也等待所有这些线程完成。