C 编程分段错误:11 个线程问题
C programming Segmentation fault: 11 Thread issues
为什么我 运行 我的代码会出现这个错误?
错误:RUN FINISHED; Segmentation fault: 11; real time: 3s; user: 0ms; system: 0m
我正在创建 10 个线程,每个线程都是一个售票员。有一个 10by10 的数组,用来存放门票的座位。根据售票员的类型,一个人将被出售那个特定的座位。
pthreads 有问题吗?
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: ticketsellers.c
* Author: iantheflyinghawaiian
*
* Created on July 4, 2016, 11:27 AM
*/
#include <stdio.h>
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// seller thread to serve one time slice (1 minute)
int theatre[10][10] ;
struct node
{
int info;
struct node *ptr;
}*front,*rear,*temp,*front1;
int count = 0;
/* Create an empty queue */
void create()
{
front = rear = NULL;
}
/* Returns queue size */
void queuesize()
{
printf("\n Queue size : %d", count);
}
/* Enqueing the queue */
void enq(int data)
{
if (rear == NULL)
{
rear = (struct node *)malloc(1*sizeof(struct node));
rear->ptr = NULL;
rear->info = data;
front = rear;
}
else
{
temp=(struct node *)malloc(1*sizeof(struct node));
rear->ptr = temp;
temp->info = data;
temp->ptr = NULL;
rear = temp;
}
count++;
}
/* Displaying the queue elements */
void display()
{
front1 = front;
if ((front1 == NULL) && (rear == NULL))
{
printf("Queue is empty");
return;
}
while (front1 != rear)
{
printf("%d ", front1->info);
front1 = front1->ptr;
}
if (front1 == rear)
printf("%d", front1->info);
}
/* Dequeing the queue */
void deq()
{
front1 = front;
if (front1 == NULL)
{
printf("\n Error: Trying to display elements from empty queue");
return;
}
else
if (front1->ptr != NULL)
{
front1 = front1->ptr;
printf("\n Dequed value : %d", front->info);
free(front);
front = front1;
}
else
{
printf("\n Dequed value : %d", front->info);
free(front);
front = NULL;
rear = NULL;
}
count--;
}
/* Returns the front element of queue */
int frontelement()
{
if ((front != NULL) && (rear != NULL))
return(front->info);
else
return 0;
}
/* Display if queue is empty or not */
void empty()
{
if ((front == NULL) && (rear == NULL))
printf("\n Queue empty");
else
printf("Queue not empty");
}
//Ticket Seller
void * sell(char *seller_type)
{
char seller_type1;
seller_type1 = *seller_type;
int i;
i = 0;
while (i == 0);
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
// Serve any buyer available in this seller queue that is ready
// now to buy ticket till done with all relevant buyers in their queue
//………………
// Case statements for seller_types
switch(seller_type1)
{
case 'H' :
printf("Seller type: H\n");
i = 1;
break;
case 'M' :
printf("Seller type: M\n");
i = 1;
break;
case 'L' :
printf("Seller type: L\n");
i = 1;
break;
}
}
return NULL; // thread exits
}
void wakeup_all_seller_threads()
{
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
}
int main()
{
int i, N;
pthread_t tids[10];
printf("Enter N value of Customers: ");
scanf("%d", &N);
printf("Number of Customers: %d", N);
char seller_type;
// Create necessary data structures for the simulator.
// Create buyers list for each seller ticket queue based on the
// N value within an hour and have them in the seller queue.
// Create 10 threads representing the 10 sellers.
seller_type = 'H';
pthread_create(&tids[i], NULL, sell, &seller_type);
seller_type = 'M';
for (i = 1; i < 4; i++)
pthread_create(&tids[i], NULL, sell, &seller_type);
seller_type = 'L';
for (i = 4; i < 10; i++)
pthread_create(&tids[i], NULL, sell, &seller_type);
// wakeup all seller threads
wakeup_all_seller_threads();
// wait for all seller threads to exit
for (i = 0 ; i < 10 ; i++)
pthread_join(&tids[i], NULL);
// Printout simulation results
//…………
exit(0);
}
将 seller_type
传递给新创建的线程,同时修改主线程中的变量时发生数据竞争。
传递给 pthread_create
的函数类型必须是:void*(*)(void*)
,而不是您正在使用的类型。
函数 pthread_join
需要一个类型 pthread_t
作为第一个参数,而不是指向该类型的指针,这是您传递给它的。
main 中的变量 i
未初始化,用于在第一个 pthread_create 调用中索引数组 tids
。
所有这四个问题本身都会导致未定义的行为。我怀疑最后一个导致崩溃。
正如@2501 已经假设的那样:导致段错误的罪魁祸首是 main
.
中未初始化的变量 i
我冒昧地为您的 pthread 创建编写了一个最小示例,并添加了一些 printf。
编译时没有警告
gcc -W -Wall threadtest.c -o threadtest -pthread
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
struct seller_type {
char st;
int tid;
};
void *sell(void *arg)
{
struct seller_type *seller_type1 = arg;
int i;
i = 0;
printf("thread #%d: seller_type1->st = %c\n", seller_type1->tid,
seller_type1->st);
// no semicolon after while()
while (i == 0) {
switch (seller_type1->st) {
case 'H':
printf("Seller type: H\n");
i = 1;
break;
case 'M':
printf("Seller type: M\n");
i = 1;
break;
case 'L':
printf("Seller type: L\n");
i = 1;
break;
}
}
printf("thread #%d: Work done\n", seller_type1->tid);
return NULL;
}
int main()
{
int i = 0;
struct seller_type *seller_type1;
pthread_t tids[10];
seller_type1 = calloc(10, sizeof(struct seller_type));
// All error handling ommitted! Yes, ALL!
seller_type1[0].st = 'H';
seller_type1[0].tid = 0;
pthread_create(&tids[0], NULL, sell, &seller_type1[0]);
for (i = 1; i < 4; i++) {
seller_type1[i].st = 'M';
seller_type1[i].tid = i;
pthread_create(&tids[i], NULL, sell, &seller_type1[i]);
}
for (i = 4; i < 10; i++) {
seller_type1[i].st = 'L';
seller_type1[i].tid = i;
pthread_create(&tids[i], NULL, sell, &seller_type1[i]);
}
puts("All threads created");
// wait for all seller threads to exit
for (i = 0; i < 10; i++) {
pthread_join(tids[i], NULL);
printf("Thread %d joined\n", i);
}
puts("All threads joined");
exit(EXIT_SUCCESS);
}
我希望你能以此为基础。
为什么我 运行 我的代码会出现这个错误?
错误:RUN FINISHED; Segmentation fault: 11; real time: 3s; user: 0ms; system: 0m
我正在创建 10 个线程,每个线程都是一个售票员。有一个 10by10 的数组,用来存放门票的座位。根据售票员的类型,一个人将被出售那个特定的座位。
pthreads 有问题吗?
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: ticketsellers.c
* Author: iantheflyinghawaiian
*
* Created on July 4, 2016, 11:27 AM
*/
#include <stdio.h>
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// seller thread to serve one time slice (1 minute)
int theatre[10][10] ;
struct node
{
int info;
struct node *ptr;
}*front,*rear,*temp,*front1;
int count = 0;
/* Create an empty queue */
void create()
{
front = rear = NULL;
}
/* Returns queue size */
void queuesize()
{
printf("\n Queue size : %d", count);
}
/* Enqueing the queue */
void enq(int data)
{
if (rear == NULL)
{
rear = (struct node *)malloc(1*sizeof(struct node));
rear->ptr = NULL;
rear->info = data;
front = rear;
}
else
{
temp=(struct node *)malloc(1*sizeof(struct node));
rear->ptr = temp;
temp->info = data;
temp->ptr = NULL;
rear = temp;
}
count++;
}
/* Displaying the queue elements */
void display()
{
front1 = front;
if ((front1 == NULL) && (rear == NULL))
{
printf("Queue is empty");
return;
}
while (front1 != rear)
{
printf("%d ", front1->info);
front1 = front1->ptr;
}
if (front1 == rear)
printf("%d", front1->info);
}
/* Dequeing the queue */
void deq()
{
front1 = front;
if (front1 == NULL)
{
printf("\n Error: Trying to display elements from empty queue");
return;
}
else
if (front1->ptr != NULL)
{
front1 = front1->ptr;
printf("\n Dequed value : %d", front->info);
free(front);
front = front1;
}
else
{
printf("\n Dequed value : %d", front->info);
free(front);
front = NULL;
rear = NULL;
}
count--;
}
/* Returns the front element of queue */
int frontelement()
{
if ((front != NULL) && (rear != NULL))
return(front->info);
else
return 0;
}
/* Display if queue is empty or not */
void empty()
{
if ((front == NULL) && (rear == NULL))
printf("\n Queue empty");
else
printf("Queue not empty");
}
//Ticket Seller
void * sell(char *seller_type)
{
char seller_type1;
seller_type1 = *seller_type;
int i;
i = 0;
while (i == 0);
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
// Serve any buyer available in this seller queue that is ready
// now to buy ticket till done with all relevant buyers in their queue
//………………
// Case statements for seller_types
switch(seller_type1)
{
case 'H' :
printf("Seller type: H\n");
i = 1;
break;
case 'M' :
printf("Seller type: M\n");
i = 1;
break;
case 'L' :
printf("Seller type: L\n");
i = 1;
break;
}
}
return NULL; // thread exits
}
void wakeup_all_seller_threads()
{
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
}
int main()
{
int i, N;
pthread_t tids[10];
printf("Enter N value of Customers: ");
scanf("%d", &N);
printf("Number of Customers: %d", N);
char seller_type;
// Create necessary data structures for the simulator.
// Create buyers list for each seller ticket queue based on the
// N value within an hour and have them in the seller queue.
// Create 10 threads representing the 10 sellers.
seller_type = 'H';
pthread_create(&tids[i], NULL, sell, &seller_type);
seller_type = 'M';
for (i = 1; i < 4; i++)
pthread_create(&tids[i], NULL, sell, &seller_type);
seller_type = 'L';
for (i = 4; i < 10; i++)
pthread_create(&tids[i], NULL, sell, &seller_type);
// wakeup all seller threads
wakeup_all_seller_threads();
// wait for all seller threads to exit
for (i = 0 ; i < 10 ; i++)
pthread_join(&tids[i], NULL);
// Printout simulation results
//…………
exit(0);
}
将 seller_type
传递给新创建的线程,同时修改主线程中的变量时发生数据竞争。
传递给 pthread_create
的函数类型必须是:void*(*)(void*)
,而不是您正在使用的类型。
函数 pthread_join
需要一个类型 pthread_t
作为第一个参数,而不是指向该类型的指针,这是您传递给它的。
main 中的变量 i
未初始化,用于在第一个 pthread_create 调用中索引数组 tids
。
所有这四个问题本身都会导致未定义的行为。我怀疑最后一个导致崩溃。
正如@2501 已经假设的那样:导致段错误的罪魁祸首是 main
.
i
我冒昧地为您的 pthread 创建编写了一个最小示例,并添加了一些 printf。
编译时没有警告
gcc -W -Wall threadtest.c -o threadtest -pthread
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
struct seller_type {
char st;
int tid;
};
void *sell(void *arg)
{
struct seller_type *seller_type1 = arg;
int i;
i = 0;
printf("thread #%d: seller_type1->st = %c\n", seller_type1->tid,
seller_type1->st);
// no semicolon after while()
while (i == 0) {
switch (seller_type1->st) {
case 'H':
printf("Seller type: H\n");
i = 1;
break;
case 'M':
printf("Seller type: M\n");
i = 1;
break;
case 'L':
printf("Seller type: L\n");
i = 1;
break;
}
}
printf("thread #%d: Work done\n", seller_type1->tid);
return NULL;
}
int main()
{
int i = 0;
struct seller_type *seller_type1;
pthread_t tids[10];
seller_type1 = calloc(10, sizeof(struct seller_type));
// All error handling ommitted! Yes, ALL!
seller_type1[0].st = 'H';
seller_type1[0].tid = 0;
pthread_create(&tids[0], NULL, sell, &seller_type1[0]);
for (i = 1; i < 4; i++) {
seller_type1[i].st = 'M';
seller_type1[i].tid = i;
pthread_create(&tids[i], NULL, sell, &seller_type1[i]);
}
for (i = 4; i < 10; i++) {
seller_type1[i].st = 'L';
seller_type1[i].tid = i;
pthread_create(&tids[i], NULL, sell, &seller_type1[i]);
}
puts("All threads created");
// wait for all seller threads to exit
for (i = 0; i < 10; i++) {
pthread_join(tids[i], NULL);
printf("Thread %d joined\n", i);
}
puts("All threads joined");
exit(EXIT_SUCCESS);
}
我希望你能以此为基础。