weixin_53881769 2022-07-05 20:28 采纳率: 100%
浏览 70
已结题

linux中的多线程问题

请问哪位可以帮我看看吗,一直在出现段错误问题,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;

}



   
  • 写回答

2条回答 默认 最新

  • 泡沫o0 2023年度博客之星上海赛道TOP 1 2022-07-06 09:43
    关注

    段错误的原因在于无效内存引用.
    问题出在于这两处.

    //错误做法,此处传入线程的是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)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 7月14日
  • 已采纳回答 7月6日
  • 创建了问题 7月5日

悬赏问题

  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助