线程不识别标志中的变化

时间:2016-02-25 21:45:24

标签: c multithreading synchronization pthreads

我使用几个线程。只要exit_flag设置为false,所有都在运行。

我有一个特定的主题,它不会识别标志中的变化,因此没有结束并释放其资源,我试图了解原因。

UPDATE:在使用gdb调试一下后,我可以看到给定的足够时间'有问题的线程会检测到标志更改。 我的结论是,线程没有足够的时间来检测正常运行中的变化。

我如何延迟'我的主线程,足够让所有线程检测到标志更改,而不必加入它们? (exit_flag的使用是为了不加入线程,因为我不想管理所有线程ID - 我只是分离它们中的每一个,除了处理输入的线程)。 我已尝试在sleep(5)方法中使用close_server(),在标志更改后,没有运气

注意:

  1. 相同标志上循环的其他线程会成功终止

  2. exit_flag声明是:static volatile bool exit_flag

  3. 所有主题读取标志,仅在close_server()方法中更改标志值(仅限于此)

  4. 线程在更改之前读取标志时可能发生的数据争用对我来说并不重要,只要在while循环的下一次迭代中它将读取正确的值。 / p>

  5. 线程本身没有错误(根据strerr& stdout,它们是' clean'来自错误消息(对于我在线程中处理的错误)

  6. 即使在评论整个while((!exit_flag) && (remain_data > 0))代码块时也会出现这种情况 - 所以这不是sendfile挂起的问题

  7. station_info_t struct:

    typedef struct station_info {
        int socket_fd;
        int station_num;
    } station_info_t;
    

    有问题的线程代码:

    void * station_handler(void * arg_p)
    {
        status_type_t rs = SUCCESS;
    
        station_info_t * info = (station_info_t *)arg_p;
        int remain_data = 0;
        int sent_bytes = 0;
        int song_fd = 0;
        off_t offset = 0;
        FILE * fp = NULL;
        struct stat file_stat;
    
        /* validate station number for this handler */
        if(info->station_num < 0) {
            fprintf(stderr, "station_handler() station_num = %d, something's very wrong! exiting\n", info->station_num);
            exit(EXIT_FAILURE);
        }
    
        /* Open the file to send, and get his stats */
        fp = fopen(srv_params.songs_names[info->station_num], "r");
    
        if(NULL == fp) {
            close(info->socket_fd);
            free(info);
            error_and_exit("fopen() failed! errno = ", errno);
        }
    
        song_fd = fileno(fp);
    
        if( fstat(song_fd, &file_stat) ) {
            close(info->socket_fd);
            fclose(fp);
            free(info);
            error_and_exit("fstat() failed! errno = ", errno);
        }
    
        /** Run as long as no exit procedure was initiated */
        while( !exit_flag ) {
            offset = 0;
            remain_data = file_stat.st_size;
    
            while( (!exit_flag) && (remain_data > 0) ) {
                sent_bytes = sendfile(info->socket_fd, song_fd, &offset, SEND_BUF);
                if(sent_bytes < 0 ) {
                    error_and_exit("sendfile() failed! errno = ", errno);
                }
    
                remain_data = remain_data - sent_bytes;
                usleep(USLEEP_TIME);
            }
        }
    
        printf("Station %d handle exited\n", info->station_num);
    
        /* Free \ close all resources */
        close(info->socket_fd);
        fclose(fp);
        free(info);
        return NULL;
    }
    

    我很乐意得到一些帮助。 谢谢你们

1 个答案:

答案 0 :(得分:0)

好吧,正如 user362924 所述,主要问题是我没有加入主线程中的主题,因此不允许他们有足够的时间退出。

对此问题的解决方法,如果由于某种原因,人们不想加入所有线程并动态管理线程ID,则在主线程的末尾使用sleep命令,几秒钟。

当然这种解决方法不是一种好的做法,也不推荐(对于那些通过谷歌来到这里的人)