请问哪位可以帮我看看吗,一直在出现段错误问题,linux中的多线程问题。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <semaphore.h>
#include <time.h>
#include <stdbool.h>
#define ALL 200
#define SCAN_GROUP 3
#define COLLECT_GROUP 6
#define ALL_GROUP 10
struct people
{
int name;
int number;//队列A,B中首项指队列目前人数,其他项指在该队列中的序号
int above;//首项指经过的所有人数;其他项指在200人中的序号(1-200)
char if_scan[5];//yes or no
char if_check[5];//yes or no
};
struct people queue_A[SCAN_GROUP][100];
struct people queue_B[COLLECT_GROUP][100];
int all[ALL];
int N=0;//目前已经分配allot的人数
int N_c = 0;//目前已经检测完collect的人数
int t = 0;
sem_t s;
pthread_mutex_t mutex1=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex3=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex4=PTHREAD_MUTEX_INITIALIZER;
pthread_t thread[ALL_GROUP];
void *allot(void *index)
{
int m;
int i = 0;
printf("%d",i);
while(i<SCAN_GROUP)
{
for(int j=0;j<10;j++)
{
pthread_mutex_lock(&mutex1);
queue_A[i][0].number += 1;
queue_A[i][0].above += 1;
m = queue_A[i][0].above;
queue_A[i][m].name = all[N];
queue_A[i][m].number = m;
N=N+1;
queue_A[i][m].above = N;
pthread_mutex_unlock(&mutex1);
usleep(1);
pthread_mutex_lock(&mutex4);
t += 1;
pthread_mutex_unlock(&mutex4);
}
i += 1;
}
for(N;N<200;N++)
{
i = N % SCAN_GROUP;
pthread_mutex_lock(&mutex1);
queue_A[i][0].number += 1;
queue_A[i][0].above += 1;
m = queue_A[i][0].above;
queue_A[i][m].name = all[N];
queue_A[i][m].number = m;
N=N+1;
queue_A[i][m].above = N;
pthread_mutex_unlock(&mutex1);
usleep(1);
pthread_mutex_lock(&mutex4);
t += 1;
pthread_mutex_unlock(&mutex4);
}
}
void *scan(void *index)
{
int index_a = *(int*) index;
while(true)
{
int w = queue_A[index_a][0].number;
if(w>=10||(w<10&&N>=200))
{
sem_wait(&s);
usleep(8);
pthread_mutex_lock(&mutex4);
t += 8;
pthread_mutex_unlock(&mutex4);
int temp=queue_B[0][0].number;
int k=0;
for(int b=1;b<COLLECT_GROUP;b++) //k,b为B类队列序号;选择B类队列中目前人数最少的那一队
{
if(queue_B[b][0].number<temp)
{
k=b;
temp=queue_B[b][0].number;
}
}
for(int n=0;n<10;n++)
{
int a_now = queue_A[index_a][0].above - queue_A[index_a][0].number + 1;//从队列中目前还未扫码的算起
if((a_now<=queue_A[index_a][0].above)&&(a_now>=0))
{
pthread_mutex_lock(&mutex1);
strcpy(queue_A[index_a][a_now].if_scan,"yes");
queue_A[index_a][0].number -= 1;
pthread_mutex_unlock(&mutex1);
usleep(3);
pthread_mutex_lock(&mutex4);
t += 3;
pthread_mutex_unlock(&mutex4);
pthread_mutex_lock(&mutex2);
queue_B[k][0].number += 1;
queue_B[k][0].above +=1;
int m = queue_B[k][0].above;
queue_B[k][m].name = queue_A[index_a][a_now].name;
queue_B[k][m].number = m;
queue_B[k][m].above = queue_A[index_a][a_now].above;
strcpy(queue_B[k][m].if_scan,"yes");
pthread_mutex_unlock(&mutex2);
}
else
break;
}
sem_post(&s);
usleep(8);
pthread_mutex_lock(&mutex4);
t += 8;
pthread_mutex_unlock(&mutex4);
}
w = queue_A[index_a][0].number;
if((N>=200)&&(w==0))
break;
}
}
void *collect(void *index)
{
int index_b = *(int*) index;
while(true)
{
int b_now = queue_B[index_b][0].above - queue_B[index_b][0].number + 1;//从队列中目前还未检测的算起
pthread_mutex_lock(&mutex2);
strcpy(queue_B[index_b][b_now].if_check,"yes");
queue_B[index_b][0].number -= 1;
pthread_mutex_unlock(&mutex2);
pthread_mutex_lock(&mutex3);
N_c += 1;
pthread_mutex_unlock(&mutex3);
usleep(5);
pthread_mutex_lock(&mutex4);
t += 5;
pthread_mutex_unlock(&mutex4);
printf("name:%d,number:%d,if_scan:%s,if_check:%s\n",queue_B[index_b][b_now].name,queue_B[index_b][b_now].above,queue_B[index_b][b_now].if_scan,queue_B[index_b][b_now].if_check);
if(N_c>=200)
break;
}
}
int main()
{
for(int a=0;a<SCAN_GROUP;a++)
{
queue_A[a][0].number = 0;
queue_A[a][0].above = 0;
}
for(int a=0;a<COLLECT_GROUP;a++)
{
queue_B[a][0].number = 0;
queue_B[a][0].above = 0;
}
sem_init(&s,0,3);
int i;
pthread_mutex_init (&mutex1, NULL);
pthread_mutex_init (&mutex2, NULL);
pthread_mutex_init (&mutex3, NULL);
pthread_mutex_init (&mutex4, NULL);
for(i=0;i<ALL;i++)
{
all[i] = i;
}
i = ALL_GROUP-1;
if(pthread_create(&thread[i],NULL,allot,NULL))
{
perror("Pthread Create Fails");
exit(1);
}
for (i=0;i<SCAN_GROUP;i++)
{
if(pthread_create(&thread[i],NULL,scan,(void*)i))
{
perror("Pthread Create Fails");
exit(1);
}
}
for(i=SCAN_GROUP;i<SCAN_GROUP+COLLECT_GROUP;i++)
{
if(pthread_create(&thread[i],NULL,collect,(void*)i))
{
perror("Pthread Create Fails");
exit(1);
}
}
if(pthread_join(thread[ALL_GROUP-1],NULL))
perror("Pthread Join Fails");
for (i=0;i<SCAN_GROUP;i++)
{
if(pthread_join(thread[i],NULL))
perror("Pthread Join Fails");
}
for (i=0;i<COLLECT_GROUP;i++)
{
if(pthread_join(thread[i+SCAN_GROUP],NULL))
perror("Pthread Join Fails");
}
printf("a1 = %d,a2 = %d,a3 = %d\n",queue_A[0][0].above,queue_A[1][0].above,queue_A[2][0].above);
printf("b1 = %d,b2 = %d,b3 = %d,b4 = %d,b5 = %d,b6 = %d\n",queue_B[0][0].above,queue_B[1][0].above,queue_B[2][0].above,queue_B[3][0].above,queue_B[4][0].above,queue_B[5][0].above);
pthread_mutex_destroy(&mutex1);
pthread_mutex_destroy(&mutex2);
pthread_mutex_destroy(&mutex3);
pthread_mutex_destroy(&mutex4);
return 0;
}
段错误的原因在于无效内存引用.
问题出在于这两处.
//错误做法,此处传入线程的是int类型的值,并不是地址.造成赋值给index_a一个不存在的地址
pthread_create(&thread[i],NULL,scan,(void*)i)
int index_a = *(int*) index;//172
//另一个线程同理
//传参时由于是指针,所以需要对int类型的i取地址.传入地址才行.
//正确做法
pthread_create(&thread[i],NULL,scan,(void*)&i)
这篇文章讲的很详细,请看:Linux的多线程