p_thread中传递的数据消失,导致EXC_BAD_ACCESS

时间:2014-06-08 07:09:24

标签: c++ c multithreading macos

我有一个服务器/客户端应用程序,多个客户端连接到服务器并发送数据,这些数据会根据threadNo分割并显示在不同的字段中。

只要main.cpp中没有线程,我的代码工作正常,但是只要我在main.cpp中启动一个线程以接受输入并同时运行服务器,我就拥有了在我的connection.cpp中设置开始表现得非常奇怪。没有重叠的名字。

使用断点我发现有时connection.cpp中的新线程不会传递它们的数据结构,有时它们会传递。无论如何,当客户端尝试连接时崩溃,因为数据结构中没有数据。 (clearData()程序无关)

它不是随机的,因为我可以可靠地使它崩溃,但很难弄清楚它为什么会发生。因此,我已经包含了main.cpp和connection.cpp的全部内容。

我很缺乏经验,对于凌乱的代码和许多不良做法感到抱歉。它主要是OSX依赖的,可能适用于unix。希望能缩短它但它以简单的形式工作。

connection -Works罚款“工作”主

#include "connection.h"
#include "display.h"
#include "dataSort.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "pthread.h"

struct thread_data{
    int  threadNo;
    int sockNo;
    pthread_t threadC;
};



void *recData(void *data){//start server

    clearData();
    struct thread_data *threadData;
    threadData = (struct thread_data*) data;

    char buf[75];//35
    int k;

    while(1)
    {
        k = recv((*threadData).sockNo, buf, 75, 0);//35
        if (k == -1)
        {
            printf("\ncannot read from client!\n");
            break;
        }

        if (k == 0)
        {
            close((*threadData).sockNo);
            int client = (*threadData).threadNo;
            clearData();
            printf("Client %d Disconnected\n",client); //print this here so program doesnt have to end when a client disconnects
            sleep(2);
            break;
        }

        if (k > 0){
            //printf("%d\n",(*threadData).threadNo);
            dataSort(buf,(*threadData).threadNo);
            displayData();
        }
        //what now....
        //break;
    }

    //close(threadData->sockNo);
    return NULL;
}

void *acceptConn(void *data){
    struct thread_data *threadData;
    threadData = (struct thread_data*) data;

    pthread_t thread;
    void *status;
    int sock_desc = (*threadData).sockNo;

    struct sockaddr_in client;
    memset(&client, 0, sizeof(client));
    socklen_t len = sizeof(client);


    int i = (*threadData).threadNo;
    int j = (*threadData).sockNo;
    sleep(1);
    int temp_sock_desc= accept(3, (struct sockaddr*)&client, &len); //Wait for connection.

    if (temp_sock_desc == -1){
        //Accept connection didnt work.
    }

    (*threadData).sockNo = temp_sock_desc;

    pthread_create(&thread, NULL, recData, (void *)threadData);
    int rc = pthread_join(thread, &status);
    if (rc) {
        printf("Error waiting for thread\n");
    }
    //printf("Connection finished\n");

    return NULL;
}


void *checkThreads(void *data){
    struct thread_data *threadData;
    threadData = (struct thread_data*) data;

    void *status;
    pthread_t thread[1];
    pthread_t watchthread = (*threadData).threadC;
    int i = (*threadData).threadNo;
    int j = (*threadData).sockNo;
    printf("Thread ID:%d\n",i);
    printf("Socket No:%d\n",j);

    pthread_join(watchthread, &status);
    while (i < 3){
        pthread_create(thread, NULL, acceptConn, (void *)threadData);
        watchthread = (*threadData).threadC;
        pthread_join(watchthread, &status);
    }

    return NULL;
}


int startHost()
{
    printf("host created\n");

    int sock_desc = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_desc == -1)
    {
        printf("cannot create socket!\n");
        return 5; //Can't create socket
    }

    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(9025);

    if (bind(sock_desc, (struct sockaddr*)&server, sizeof(server)) != 0)
    {
        close(sock_desc);
        printf("cannot bind socket!\n");
        sleep(2);
        return 6; //no more connections available or socket not binded
    }

    if (listen(sock_desc, 10) != 0)
    {
        close(sock_desc);
        printf("cannot listen on socket!\n");
        return 5; //cant listen on socket (this error hasnt happened yet, just in case)
    }

    pthread_t thread[3];
    pthread_t threadHelper[3];
    struct thread_data threadID[3];//create a thread structure. threadID and socketID


    for(int i=0; i < 3; i++ ){
        threadID[i].threadNo = i;
        threadID[i].sockNo = sock_desc;
        pthread_create(&thread[i], NULL, acceptConn, (void *)&threadID[i]);
        sleep(0.5);
        threadID[i].threadC = thread[i];
        pthread_create(&threadHelper[i], NULL, checkThreads, (void *)&threadID[i]);
    }


    pthread_exit(thread);
    close(sock_desc);//socket closed
    printf("server shutdown\n");
    sleep(2);


    return 0;
}

不工作 -

#include <iostream>
#include "connection.h"
#include <unistd.h>
struct main_thread{
    int hasQuit;
};

void *runServer(void *data){

    struct main_thread *mainData;
    mainData = (struct main_thread*) data;
    while ((*mainData).hasQuit == 0){

        int debugCode;
        int i = 0;

        while (i == 0) {
            debugCode = startHost();
            switch (debugCode) {
                case 2:
                    printf("\nClient disconnected.\n");
                    i = 1;
                    break;
                case 3:
                    printf("Cannot accept client!\n");
                    break;
                case 5:
                    printf("Socket Error. Please check network settings and status.\n");
                    i = 1;
                    break;
                case 6:

                    break;
                case 0:
                    printf("Server closed successfully\n");
                    break;
                default:
                    break;
            }
        }
        sleep(30);//prevents spamming the network if server cannot start.
        //set so high because user is most likely at server and can manually
        //quit and re-start. otherwise time is needed for port to free automatically.
    }
    return NULL;
}




void *readInput(void *data){
    struct main_thread *mainData;
    mainData = (struct main_thread*) data;
    char input[5];

    while (true){
        scanf ("%s",input);
        if ((strncmp(input, "quit", 4))||
            (strncmp(input, "Quit", 4))||
            (strncmp(input, "exit", 4))||
            (strncmp(input, "Exit", 4)) == 0)
        {
            (*mainData).hasQuit = 1;
            break;
        }
    }
    return NULL;
}



int main(int argc, const char * argv[])
{
    printf("Starting server on socket:%s\n",argv[1]);
    printf("'Exit' or 'Quit' to close client\n");


    pthread_t mainthread[2];
    struct main_thread mainData;
    void *Mstatus;

    mainData.hasQuit = 0;

    while (mainData.hasQuit == 0){
        pthread_create(&mainthread[0], NULL, runServer, &mainData);
        pthread_create(&mainthread[1], NULL, readInput,&mainData);
        pthread_join(mainthread[1], &Mstatus);
    }

    printf("Server exiting...\n");
    return 0;
}

Working-main

#include <iostream>
#include "connection.h"
#include <unistd.h>


void runServer(){

    int debugCode;
    int i = 0;

    while (i == 0) {
        debugCode = startHost();
        switch (debugCode) {
            case 2:
                printf("\nClient disconnected.\n");
                i = 1;
                break;
            case 3:
                printf("Cannot accept client!\n");
                break;
            case 5:
                printf("Socket Error. Please check network settings and status.\n");
                i = 1;
                break;
            case 6:

                break;
            case 0:
                printf("Server closed successfully\n");
                break;
            default:
                break;
        }
    }
}





int main(int argc, const char * argv[])
{
    runServer();
    return 0;
}

0 个答案:

没有答案