生产者-消费者 c - 更大值的分段错误
producer-consumer c - segmentation fault for bigger values
我正在用 c 中的两个线程解决一个生产者一个消费者问题。我使用一个共享链表来做到这一点,生产者在其中放置一些东西,而消费者从同一个列表中获取它。
我必须 运行 我的代码有 2 个值 N 和 B(N 是要传输的数据的大小,B 是共享链表的最大大小)。
(./thread-a1 N B)
此代码 运行 适用于较小的值。但是,对于 N = 20,000 和 B = 16,它会给出 Segmentation fault: 11
我不知道为什么会这样。请帮忙
#include<time.h>
#include<sys/time.h>
#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
struct job
{
int data;
struct job* next;
};
struct job* head;
int maxSize;
int n;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int getCount()
{
int count = 0;
struct job* p = head;
while(p != NULL)
{
p = p -> next;
count++;
}
return count;
}
void Insert(int x)
{
struct job* temp = (struct job*)malloc(sizeof(struct job));
temp -> data = x;
if (head == NULL)
{
temp -> next = NULL;
}
else
{
temp -> next = head;
}
head = temp;
}
void Delete()
{
struct job *toDelete, *secondLastNode;
if(head == NULL)
{
}
else
{
toDelete = head;
secondLastNode = head;
while(toDelete->next != NULL)
{
secondLastNode = toDelete;
toDelete = toDelete->next;
}
printf("%d, ", toDelete -> data);
if(toDelete == head)
{
free(toDelete);
head = NULL;
}
else
{
secondLastNode->next = NULL;
free(toDelete);
}
}
}
void* producer(void* arg)
{
pthread_mutex_lock(&m);
head = NULL;
int i;
for (i = 0; i<n; i++)
{
while(getCount() >= maxSize)
{
pthread_mutex_unlock(&m);
}
Insert(i);
}
return NULL;
}
void* consumer(void* arg)
{
pthread_mutex_lock(&m);
int i;
for (i=0; i<n; i++)
{
while(getCount() <= 0)
{
pthread_mutex_unlock(&m);
}
Delete();
}
return NULL;
}
int main(int argc, char *argv[])
{
struct timeval start_init, end_init;
gettimeofday(&start_init, NULL);
n = atoi(argv[1]);
maxSize = atoi(argv[2]);
pthread_t thread1;
pthread_t thread2;
gettimeofday(&end_init, NULL);
printf("Time elapsed for initialization is: %ld\n",
(long)(end_init.tv_sec*1000000 + end_init.tv_usec) - (start_init.tv_sec*1000000 + start_init.tv_usec));
struct timeval start_trans, end_trans;
gettimeofday(&start_trans, NULL);
pthread_create(&thread1, NULL, &producer, NULL);
pthread_create(&thread2, NULL, &consumer, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
gettimeofday(&end_trans, NULL);
printf("Time elapsed for transmission is: %ld\n",
(long)(end_trans.tv_sec*1000000 + end_trans.tv_usec) - (start_trans.tv_sec*1000000 + start_trans.tv_usec));
return 0;
}
您需要重新检查您的锁定;您只在每个生产者和消费者开始时获取锁,然后只解锁它们(重复!),这意味着不会发生进一步的同步。您的程序运行的时间越长,这种缺乏同步的情况越有可能使您的程序出错。
我认为你的锁定应该是:
void* producer(void* arg)
{
int i;
for (i = 0; i<n; i++)
{
pthread_mutex_lock(&m);
while(getCount() >= maxSize)
{
pthread_mutex_unlock(&m); // allow consumer to acquire lock
pthread_mutex_lock(&m); // re-acquire lock
}
Insert(i);
pthread_mutex_lock(&m);
}
return NULL;
}
void* consumer(void* arg)
{
int i;
for (i=0; i<n; i++)
{
pthread_mutex_lock(&m);
while(getCount() <= 0)
{
pthread_mutex_unlock(&m); // allow producer to acquire lock
pthread_mutex_lock(&m); // re-acquire lock
}
Delete();
pthread_mutex_lock(&m);
}
return NULL;
}
请注意,包括 getCount
在内的所有操作都必须在获得锁的情况下完成。 (考虑将 getCount
替换为全局变量;仅在锁定时对其进行操作。)
我正在用 c 中的两个线程解决一个生产者一个消费者问题。我使用一个共享链表来做到这一点,生产者在其中放置一些东西,而消费者从同一个列表中获取它。 我必须 运行 我的代码有 2 个值 N 和 B(N 是要传输的数据的大小,B 是共享链表的最大大小)。 (./thread-a1 N B) 此代码 运行 适用于较小的值。但是,对于 N = 20,000 和 B = 16,它会给出 Segmentation fault: 11 我不知道为什么会这样。请帮忙
#include<time.h>
#include<sys/time.h>
#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
struct job
{
int data;
struct job* next;
};
struct job* head;
int maxSize;
int n;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int getCount()
{
int count = 0;
struct job* p = head;
while(p != NULL)
{
p = p -> next;
count++;
}
return count;
}
void Insert(int x)
{
struct job* temp = (struct job*)malloc(sizeof(struct job));
temp -> data = x;
if (head == NULL)
{
temp -> next = NULL;
}
else
{
temp -> next = head;
}
head = temp;
}
void Delete()
{
struct job *toDelete, *secondLastNode;
if(head == NULL)
{
}
else
{
toDelete = head;
secondLastNode = head;
while(toDelete->next != NULL)
{
secondLastNode = toDelete;
toDelete = toDelete->next;
}
printf("%d, ", toDelete -> data);
if(toDelete == head)
{
free(toDelete);
head = NULL;
}
else
{
secondLastNode->next = NULL;
free(toDelete);
}
}
}
void* producer(void* arg)
{
pthread_mutex_lock(&m);
head = NULL;
int i;
for (i = 0; i<n; i++)
{
while(getCount() >= maxSize)
{
pthread_mutex_unlock(&m);
}
Insert(i);
}
return NULL;
}
void* consumer(void* arg)
{
pthread_mutex_lock(&m);
int i;
for (i=0; i<n; i++)
{
while(getCount() <= 0)
{
pthread_mutex_unlock(&m);
}
Delete();
}
return NULL;
}
int main(int argc, char *argv[])
{
struct timeval start_init, end_init;
gettimeofday(&start_init, NULL);
n = atoi(argv[1]);
maxSize = atoi(argv[2]);
pthread_t thread1;
pthread_t thread2;
gettimeofday(&end_init, NULL);
printf("Time elapsed for initialization is: %ld\n",
(long)(end_init.tv_sec*1000000 + end_init.tv_usec) - (start_init.tv_sec*1000000 + start_init.tv_usec));
struct timeval start_trans, end_trans;
gettimeofday(&start_trans, NULL);
pthread_create(&thread1, NULL, &producer, NULL);
pthread_create(&thread2, NULL, &consumer, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
gettimeofday(&end_trans, NULL);
printf("Time elapsed for transmission is: %ld\n",
(long)(end_trans.tv_sec*1000000 + end_trans.tv_usec) - (start_trans.tv_sec*1000000 + start_trans.tv_usec));
return 0;
}
您需要重新检查您的锁定;您只在每个生产者和消费者开始时获取锁,然后只解锁它们(重复!),这意味着不会发生进一步的同步。您的程序运行的时间越长,这种缺乏同步的情况越有可能使您的程序出错。
我认为你的锁定应该是:
void* producer(void* arg)
{
int i;
for (i = 0; i<n; i++)
{
pthread_mutex_lock(&m);
while(getCount() >= maxSize)
{
pthread_mutex_unlock(&m); // allow consumer to acquire lock
pthread_mutex_lock(&m); // re-acquire lock
}
Insert(i);
pthread_mutex_lock(&m);
}
return NULL;
}
void* consumer(void* arg)
{
int i;
for (i=0; i<n; i++)
{
pthread_mutex_lock(&m);
while(getCount() <= 0)
{
pthread_mutex_unlock(&m); // allow producer to acquire lock
pthread_mutex_lock(&m); // re-acquire lock
}
Delete();
pthread_mutex_lock(&m);
}
return NULL;
}
请注意,包括 getCount
在内的所有操作都必须在获得锁的情况下完成。 (考虑将 getCount
替换为全局变量;仅在锁定时对其进行操作。)