Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.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 多线程,无法使另一个线程工作_C_Multithreading_Mutex - Fatal编程技术网

C 多线程,无法使另一个线程工作

C 多线程,无法使另一个线程工作,c,multithreading,mutex,C,Multithreading,Mutex,我正在尝试为提交的每个请求创建一个线程。这是我正在做的一个简短的例子。问题是,我可以将第一个输入请求写入列表,但当我尝试发送第二个请求时,当它需要向我的函数请求循环发送信号时,它就会停止工作 因此,它的工作完美,直到那里。有人知道如何解决这个问题吗?该计划不想做得比这更进一步 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #incl

我正在尝试为提交的每个请求创建一个线程。这是我正在做的一个简短的例子。问题是,我可以将第一个输入请求写入列表,但当我尝试发送第二个请求时,当它需要向我的函数请求循环发送信号时,它就会停止工作

因此,它的工作完美,直到那里。有人知道如何解决这个问题吗?该计划不想做得比这更进一步

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <string.h> 
#include "tcpsocket.h" 
#include <sys/select.h> 
#include <sys/time.h> 
#include <sys/types.h> 
#include <pthread.h> 

#define NUM_HANDLER_THREADS 3 /* number of threads used to service requests */
pthread_mutex_t request_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t got_request = PTHREAD_COND_INITIALIZER;

unsigned char buffer[BUFSIZE]; 
unsigned char collect_buffers[2000];

struct timespec timeout; 
struct timeval tv;

int num_requests = 0;
int num; 
int rc = 0;
struct request {
    int number;
    struct request* next;
};
struct request* requests = NULL;
struct request* last_request = NULL;
这是我想将数据写入列表的函数。之后,我使用以下命令删除请求:freerequest

struct request* get_request(pthread_mutex_t* p_mutex){
    printf("NUMBER REQUESTS (get request): %d\n",num_requests);    
    int rc;
    struct request* a_request;

    rc = pthread_mutex_lock(p_mutex);
    if (num_requests > 0) {
        a_request = requests;
        requests = a_request->next;
        printf("REQUEST NUMBER:%d\n",a_request->number);
        if (requests == NULL) { /* this was the last request on the list */
            last_request = NULL;
            printf("last request is NULL\n\n");
        }
        num_requests--; //remove REQUEST
    }else { /* requests list is empty */
        printf("list is empty\n");
        a_request = NULL;
    }
    //remove request
    free(a_request);

    rc = pthread_mutex_unlock(p_mutex);
    /* return the request to the caller. */
return a_request;
}
这是我处理请求的循环,直到不再有请求为止

void* handle_requests_loop(void* data){
    //rc = pthread_mutex_lock(&request_mutex);    
    printf("NUMBER REQUESTS (loop): %d\n",num_requests);
    int rc;
    struct request* a_request;
    int thread_id = *((int*)data);

    while(num_requests > 0){

        printf("THREAD ID : %d\n",thread_id);
        a_request = get_request(&request_mutex);

        if(num_requests == 0){
            printf("NO REQUESTS\n\n");
        }else{
            printf("THERE ARE REQUESTS\n\n");
        }

    }
    while(num_requests == 0){
        printf("wait");
        rc = pthread_cond_wait(&got_request, &request_mutex);

    }
}
我为此编写了一个测试函数,它生成2个线程。第一个可以正常工作,另一个在需要向线程循环发送新信号时停止工作

int main(int argc, char* argv[]){ 
    printf("StartUp\n"); 

    //---------------------------Create Threads--------------------------------
    for (i=0; i<NUM_HANDLER_THREADS; i++) {
        thr_id[i] = i;
    pthread_create(&p_threads[i], NULL, handle_requests_loop,(void*)&thr_id[i]);
    }

    //--------------------------INTERRUPT--------------------------------------
    int j;
    for(j=1;j<3;j++){
    printf("ADD REQUEST\n");
    add_request(j, &request_mutex, &got_request);

    delay.tv_sec = 5;
    delay.tv_nsec = 10;
    nanosleep(&delay,NULL);

    } 
      return 0; 
}

有人知道如何解决这个问题吗?非常感谢

我不知道你的具体问题是什么。我需要您更详细地说明当您只有一个接收方线程时会发生什么,并在调试器中运行,告诉我们每个线程都会遇到哪行代码。例如,从您的报告中不清楚卡住的是主线程还是子线程之一。当你只创建了一个子线程,更不用说两个子线程而不是三个子线程时,你是否观察到了问题还不清楚

也就是说,有一个bug,还有一些你可以清理的东西,当你试图自己解决这些问题时,这些东西会让你自己变得更容易

错误在于,在handle\u requests\u循环的底部调用pthread\u cond\u wait with&request\u mutex,即使当前没有锁定request\u mutex。这会导致未定义的行为,其中可能包括永久禁用调用pthread_cond_wait或pthread_cond_signal的一个或两个线程

在你可以清理的事情中:

您正在使用PTHREAD\u mutex\u初始值设定项初始化互斥对象。这将创建非递归互斥体。如果同一线程尝试锁定互斥锁两次,它将自身死锁。您应该使用PTHREAD_MUTEX_RECURSIVE属性初始化,或者非常小心不要双重锁定。例如:如果您在handle\u requests\u循环的第一行取消对pthread\u mutex\u lock调用的注释,那么当您在get\u请求的第5行调用pthread\u mutex\u lock时,您肯定会死锁。 在main中创建一些线程,但不调用pthread_join。现在这可能还可以,但在将来的某个时候,您可能会不假思索地调用pthread_create,并引用main堆栈上的一些数据,这将导致未定义行为的严重问题。 在离开handle_requests_循环时,既没有返回语句,也没有调用pthread_exit。您至少需要返回NULL。 我不知道你对请求和最后一个请求做了什么,而只是有一个变量。看起来是错的,但我想不出来,所以,纯属运气,可能没问题。 您正在释放get_请求底部附近的_请求,然后将其返回到处理_请求的循环中。从长远来看,这只会导致悲伤和伤感。
这可能是太多的代码让任何人都感到兴奋。试着缩小你的问题范围,并确保你真正理解了所有成分本身。谢谢你的重播!我来看看这个。我想这会帮我更进一步!谢谢我尝试了一些关于pthread join的东西。因此,当请求提交到执行函数pthread_jointhread1时,NULL。但是我如何在下一个循环中再次使用该线程呢?我在线程函数中尝试了pthread_exitNULL之类的东西,但它关闭了整个程序。你知道解决这个问题的办法吗?希望你能理解我的问题
int main(int argc, char* argv[]){ 
    printf("StartUp\n"); 

    //---------------------------Create Threads--------------------------------
    for (i=0; i<NUM_HANDLER_THREADS; i++) {
        thr_id[i] = i;
    pthread_create(&p_threads[i], NULL, handle_requests_loop,(void*)&thr_id[i]);
    }

    //--------------------------INTERRUPT--------------------------------------
    int j;
    for(j=1;j<3;j++){
    printf("ADD REQUEST\n");
    add_request(j, &request_mutex, &got_request);

    delay.tv_sec = 5;
    delay.tv_nsec = 10;
    nanosleep(&delay,NULL);

    } 
      return 0; 
}