Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的多线程TCP服务器崩溃_C_Multithreading_Sockets_Tcp - Fatal编程技术网

C中的多线程TCP服务器崩溃

C中的多线程TCP服务器崩溃,c,multithreading,sockets,tcp,C,Multithreading,Sockets,Tcp,我用C编写了一个多线程TCP服务器。当我对它运行多个测试客户端时,它崩溃了。我发现了两种类型的碰撞,它们似乎都有相同的根本原因。附带的碰撞发生在主要区域。在另一种风格中,当客户端部分想要锁定以关闭套接字时,会出现崩溃。 谁能告诉我是什么原因造成了这次车祸 TCP服务器代码: #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <sys/types.h> #inclu

我用C编写了一个多线程TCP服务器。当我对它运行多个测试客户端时,它崩溃了。我发现了两种类型的碰撞,它们似乎都有相同的根本原因。附带的碰撞发生在主要区域。在另一种风格中,当客户端部分想要锁定以关闭套接字时,会出现崩溃。 谁能告诉我是什么原因造成了这次车祸

TCP服务器代码:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h> //inet_addr
#include <pthread.h> //for threading , link with lpthread

#define BUFSIZE     2048 // TODO
#define MAXWORKERS 10

pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
const pthread_cond_t condInit = PTHREAD_COND_INITIALIZER;
pthread_cond_t idle = PTHREAD_COND_INITIALIZER;

typedef struct {
    pthread_t       tid;
    int             sd;
    pthread_cond_t  cond;
    uint8_t         num;
    uint8_t         state;
} worker_t;

worker_t     workers[MAXWORKERS]; //  reference to worker

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

/* worker thread */
void *handle_client(void *arg)
{
    worker_t* worker = (worker_t *) arg;
    int n;
    char buf[BUFSIZE];

    /* By default a new thread is joinable, we don't
     really want this (unless we do something special we
     end up with the thread equivalent of zombies). So
     we explicitly change the thread type to detached
     */

    pthread_detach(pthread_self());

    printf("Thread %ld started for client number %d (sd %d)\n", pthread_self(),
            worker->num, worker->sd);

    /* worker thread */
    while (1)
    {
        /* wait for work to do */
        while (worker->state == 0)
        {
            pthread_cond_wait(&worker->cond, &mtx);
        }
        int sd = worker->sd; /* get the updated socket fd */
        pthread_mutex_unlock(&mtx);

         n = read(sd, buf, BUFSIZE);
         if (n < 0)
             error("ERROR reading from socket");

         n = write(sd, "I got your message",18);
         if (n < 0)
             error("ERROR writing to socket");

        /* work done - set itself idle assumes that read returned EOF */
        pthread_mutex_lock(&mtx);
        close(sd);
        worker->state = 0;
        printf("Worker %d has completed work \n", worker->num);
        pthread_cond_signal(&idle); /* notifies dispatcher*/
        pthread_mutex_unlock(&mtx);
    } /* end while */

}

int main() { /* Dispatcher */
    int ld, sd;
    struct sockaddr_in skaddr;
    struct sockaddr_in from;
    int addrlen, length;
    int i;

    if ((ld = socket( AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Problem creating socket\n");
        exit(1);
    }

    skaddr.sin_family = AF_INET;
    skaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    //skaddr.sin_port = htons(0);
    skaddr.sin_port = htons(41332);

    if (bind(ld, (struct sockaddr *) &skaddr, sizeof(skaddr)) < 0) {
        perror("Problem binding\n");
        exit(0);
    }

    /* find out what port we were assigned and print it out */

    length = sizeof(skaddr);
    if (getsockname(ld, (struct sockaddr *) &skaddr, &length) < 0) {
        perror("Error getsockname\n");
        exit(1);
    }
    in_port_t pport = ntohs(skaddr.sin_port);
    printf("%d\n", pport);

    /* put the socket into passive mode (waiting for connections) */

    if (listen(ld, 5) < 0) {
        perror("Error calling listen\n");
        exit(1);
    }

    /* do some initialization */

    for (i = 0; i < MAXWORKERS; i++) {
        workers[i].state    = 0;
        workers[i].num      = i;
        workers[i].sd       = 0;
        workers[i].cond     = condInit;
        pthread_create(&workers[i].tid, NULL, handle_client, (void *) &workers[i]);
    }

    /* Dispatcher now processes incoming connections forever ... */
    while (1) {
        printf("Ready for a connection...\n");
        addrlen = sizeof(skaddr);

        printf("trying to accept a new connection\n");
        if ((sd = accept(ld, (struct sockaddr*) &from, &addrlen)) < 0) {
            perror("Problem with accept call\n");
            exit(1);
        }
        printf("Got a connection - processing...\n");
        for (i = 0; i < MAXWORKERS; i++) {
            pthread_mutex_lock(&mtx);
            if (workers[i].state == 0) /* worker i is idle – dispatch him to work */
            {
                printf("dispatch to worker number: %d \n", i);
                pthread_mutex_unlock(&mtx);
                break;
            }
            printf("worker number: %d was busy\n", i);

            pthread_mutex_unlock(&mtx);
        }

        if (i == MAXWORKERS) {
            /* all workers busy */
            pthread_mutex_lock(&mtx);
            pthread_cond_wait(&idle, &mtx); /* wait for one idle; */
            pthread_mutex_unlock(&mtx);
        } else { /* dispatch worker */
            pthread_mutex_lock(&mtx);
            workers[i].state = 1;
            workers[i].sd = sd;
            pthread_cond_signal(&workers[i].cond); /* wake up worker */
            pthread_mutex_unlock(&mtx);
        }
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括//inet\u addr
#包括//对于线程,使用lpthread链接
#定义BUFSIZE 2048//TODO
#定义MAXWORKERS 10
pthread\u mutex\u t mtx=pthread\u mutex\u初始值设定项;
const pthread_cond_t condInit=pthread_cond_初始值设定项;
pthread_cond_t idle=pthread_cond_初始值设定项;
类型定义结构{
pthread_t tid;
国际标准差;
pthread_cond_t cond;
uint8_t num;
uint8_t州;
}工人;;
工人工人[MAXWORKERS];//提及工人
无效错误(常量字符*消息)
{
佩罗尔(味精);
出口(1);
}
/*工作线程*/
void*handle\u客户端(void*arg)
{
worker\u t*worker=(worker\u t*)arg;
int n;
字符buf[BUFSIZE];
/*默认情况下,一个新线程是可连接的,我们不这样做
真的想要这个(除非我们做一些特别的事情
最后的线程相当于僵尸)
我们显式地将线程类型更改为detached
*/
pthread_detach(pthread_self());
printf(“为客户端编号%d(sd%d)启动了线程%ld)\n”,pthread_self(),
worker->num,worker->sd);
/*工作线程*/
而(1)
{
/*等待工作完成*/
而(工作者->状态==0)
{
pthread_cond_wait(&worker->cond,&mtx);
}
int sd=worker->sd;/*获取更新的套接字fd*/
pthread_mutex_unlock(&mtx);
n=读取(sd、buf、BUFSIZE);
if(n<0)
错误(“从套接字读取错误”);
n=写(sd,“我收到你的消息”,18);
if(n<0)
错误(“写入套接字时出错”);
/*工作完成-将自身设置为空闲假定读取返回EOF*/
pthread_mutex_lock(&mtx);
关闭(sd);
工人->状态=0;
printf(“工人%d已完成工作\n”,工人->数量);
pthread_cond_signal(&idle);/*通知调度程序*/
pthread_mutex_unlock(&mtx);
}/*结束时*/
}
int main(){/*调度程序*/
国际劳工组织,sd;
skaddr中的结构sockaddr_;
来自中的结构sockaddr_;
int addrlen,长度;
int i;
if((ld=socket(AF\u INET,SOCK\u STREAM,0))<0){
perror(“创建套接字时出现问题”);
出口(1);
}
skaddr.sin_family=AF_INET;
skaddr.sin\U addr.s\U addr=htonl(不适用于任何情况);
//skaddr.sin_端口=htons(0);
skaddr.sinu port=htons(41332);
if(bind(ld,(struct sockaddr*)&skaddr,sizeof(skaddr))<0){
perror(“绑定问题”);
出口(0);
}
/*找出分配给我们的端口并打印出来*/
长度=sizeof(skaddr);
if(getsockname(ld,(struct sockaddr*)&skaddr,&length)<0){
perror(“错误getsockname\n”);
出口(1);
}
in_port_t Support=ntohs(skaddr.sin_port);
printf(“%d\n”,支持);
/*将插座置于被动模式(等待连接)*/
如果(听(ld,5)<0){
perror(“调用侦听时出错\n”);
出口(1);
}
/*进行一些初始化*/
对于(i=0;i
崩溃:

Thread 11 (Thread 0x7fae90004700 (LWP 16318)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x602408 <workers+648>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae90004700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 10 (Thread 0x7fae90805700 (LWP 16317)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x6023c0 <workers+576>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae90805700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 9 (Thread 0x7fae9400c700 (LWP 16310)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x6021c8 <workers+72>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae9400c700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 8 (Thread 0x7fae91006700 (LWP 16316)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x602378 <workers+504>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae91006700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 7 (Thread 0x7fae91807700 (LWP 16315)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x602330 <workers+432>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae91807700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 6 (Thread 0x7fae9300a700 (LWP 16312)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x602258 <workers+216>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae9300a700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 5 (Thread 0x7fae92008700 (LWP 16314)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x6022e8 <workers+360>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae92008700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 4 (Thread 0x7fae92809700 (LWP 16313)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x6022a0 <workers+288>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae92809700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 3 (Thread 0x7fae9380b700 (LWP 16311)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x602210 <workers+144>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae9380b700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 2 (Thread 0x7fae9480d700 (LWP 16309)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x0000000000401024 in handle_client (arg=0x602180 <workers>) at main.c:87
#2  0x00007fae94bdf6ba in start_thread (arg=0x7fae9480d700) at pthread_create.c:333
#3  0x00007fae949153dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 1 (Thread 0x7fae94ff3700 (LWP 16308)):
#0  0x00007fae94843428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
---Type <return> to continue, or q <return> to quit---
#1  0x00007fae9484502a in __GI_abort () at abort.c:89
#2  0x00007fae9483bbd7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x7fae94beb015 "mutex->__data.__owner == 0", file=file@entry=0x7fae94beaff8 "../nptl/pthread_mutex_lock.c", line=line@entry=81, 
    function=function@entry=0x7fae94beb180 <__PRETTY_FUNCTION__.8623> "__pthread_mutex_lock") at assert.c:92
#3  0x00007fae9483bc82 in __GI___assert_fail (assertion=assertion@entry=0x7fae94beb015 "mutex->__data.__owner == 0", file=file@entry=0x7fae94beaff8 "../nptl/pthread_mutex_lock.c", line=line@entry=81, 
    function=function@entry=0x7fae94beb180 <__PRETTY_FUNCTION__.8623> "__pthread_mutex_lock") at assert.c:101
#4  0x00007fae94be1f68 in __GI___pthread_mutex_lock (mutex=mutex@entry=0x602140 <mtx>) at ../nptl/pthread_mutex_lock.c:81
#5  0x0000000000400cfa in main () at main.c:173
线程11(线程0x7fae90004700(LWP 16318)):
#0 pthread_cond_wait@@GLIBC_2.3.2()位于../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#main.c:87处的句柄_客户端(arg=0x602408)中有1 0x00000000004014
#在pthread_create的start_线程(arg=0x7fae90004700)中有2个0x00007fae94bdf6ba。c:333
#位于../sysdeps/unix/sysv/linux/x86_64/clone.S:109的克隆()中的3 0x00007fae949153dd
螺纹10(螺纹0x7fae90805700(LWP 16317)):
#0 pthread_cond_wait@@GLIBC_2.3.2()位于../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#main.c:87处的句柄_客户端(arg=0x6023c0)中有1 0x00000000004014
#在pthread_create的start_线程(arg=0x7fae90805700)中有2个0x00007fae94bdf6ba。c:333
#位于../sysdeps/unix/sysv/linux/x86_64/clone.S:109的克隆()中的3 0x00007fae949153dd
螺纹9(螺纹0x7fae9400c700(LWP 16310)):
#0 pthread_cond_wait@@GLIBC_2.3.2()位于../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1 0x000000000
    /* worker thread */
while (1)
{
    /* wait for work to do */
    pthread_mutex_lock(&mtx);
    while (worker->state == 0)
    {
        pthread_cond_wait(&worker->cond, &mtx);
    }
    int sd = worker->sd; /* get the updated socket fd */
    pthread_mutex_unlock(&mtx);