首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将局部堆栈变量排队到全局列表中,以便其他线程可以使用它

将局部堆栈变量排队到全局列表中,以便其他线程可以使用它
EN

Stack Overflow用户
提问于 2015-12-01 20:25:52
回答 3查看 61关注 0票数 0

我有一个有两个pthread的程序。

在每个节点上都有一个用于保存(char *)的全局变量列表。

在主线程中,我声明malloc并初始化a (char *),并将其排入全局列表。

第二个线程在无限循环中等待消耗全局列表中的新节点。

问题是第二个线程似乎无法使用第一线程构建的(char *),因为第一线程已经返回,因此(char *)可能已被释放。

有什么建议吗?

谢谢。

EN

回答 3

Stack Overflow用户

发布于 2015-12-01 20:37:30

线程结束时,malloc分配的内存不会自动释放。你还有其他的问题。

也许第二个线程是在一个紧密的循环中工作,所有的访问都是去寄存器,而不是内存。

票数 1
EN

Stack Overflow用户

发布于 2015-12-01 21:38:16

全局变量:

代码语言:javascript
复制
...
static pthread_t job_handler_thread;
List jobslist = NULL;
...

init()和build函数(主线程):

代码语言:javascript
复制
extern int init(void)
{
    int rc;

    jobslist = list_create(NULL);
    pthread_attr_t thread_attr;
    slurm_attr_init(&thread_attr);
    if (pthread_create(&job_handler_thread, &thread_attr,
                       _process_jobs, NULL))
            fatal("pthread_create error %m");
    slurm_mutex_lock(&pend_jobs_lock);
    rc = _load_pending_jobs();
    slurm_mutex_unlock(&pend_jobs_lock);

    return rc;
}

extern int slurm_jobcomp_log_record(struct job_record *job_ptr)
{
    char *json_job;
    int rc = SLURM_SUCCESS;

    // pass char * by reference. Inside the function
    // memory is allocated for the char *
    rc = _job_serialize(job_ptr, &json_job);

    if (rc == SLURM_SUCCESS)
            list_enqueue(jobslist, json_job);

    return rc;
}

等待消费列表节点的第二个线程:

代码语言:javascript
复制
extern void* _process_jobs()
{
    char *json_job;

    while(1)
    {
            if (list_is_empty(jobslist)) {
                    sleep(1);
                    continue;
            }
            json_job = list_dequeue(jobslist);
            // At this point I should process json_job
            // But data is not available here
            printf("%s", json_job);
    }

}

票数 0
EN

Stack Overflow用户

发布于 2015-12-03 03:11:08

发布的代码包含几个问题,比如没有等待线程退出。

推荐以下代码,该代码已在ubuntu linux 14.04上经过测试,运行正常

注意pthread_mutex_lock()和pthread_mutex_unlock()的用法

注意pthread_join()的用法

一般来说,代码需要写得尽可能简单,但不能更简单。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX_JOBS     (25)
#define MAX_DATA_LEN (25)

struct node
{
    int last;
    char data[MAX_DATA_LEN];
    struct node *next;
};


static pthread_t       thread_id;
static struct node    *jobsList = NULL;
static pthread_mutex_t jobsMutex =  PTHREAD_MUTEX_INITIALIZER;

void         putNode( struct node * newNode );
struct node *getNode( void );
struct node *createNode( void );

void* process_job( void* );


int main( void )
{
    if( 0 != pthread_create( &thread_id, NULL, process_job, NULL) )
    {
        perror( "pthread_create failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, pthread_create successful

    int done = 0;
    while( !done )
    {
        struct node *newNode = NULL;
        if( NULL  == (newNode = createNode() ) )
        {
            done = 1;
        }

        else
        {
            putNode( newNode );
        }
    }

    pthread_join( thread_id, NULL);
    pthread_mutex_destroy( &jobsMutex );
    return 0;
} // end function: main


struct node* createNode()
{
    static  char dataCount = 0;
    char         data[ MAX_DATA_LEN ] = {'\0'};
    struct node *newNode = NULL;

    if( MAX_JOBS > dataCount )
    {
        if( NULL != (newNode = malloc( sizeof( struct node ) ) ) )
        {
            newNode->last = ( dataCount < (MAX_JOBS-1) )? 0 : 1;
            dataCount++;
            newNode->next = NULL;

            sprintf( data, "%s %d", "this is node: ", dataCount );
            strcpy( newNode->data, data );
        }
    }

    return newNode;
} // end function: createNode


void putNode( struct node *newNode )
{
    struct node *current = NULL;

    pthread_mutex_lock( &jobsMutex );

    if( !jobsList)
    {
        jobsList = newNode;
    }

    else
    {
        for( current = jobsList; current->next; current = current->next);

        current->next = newNode;
    }

    pthread_mutex_unlock( &jobsMutex );
} // end function: putNode


// the thread process
void *process_job( void *parm )
{
    (void) parm;
    struct node * newNode;

    int done = 0;
    while( !done )
    {
        while(1)
        {
            if(NULL == (newNode = getNode() ) )
            {
                sleep(1);
            }

            else
            {
                break;
            }
        }

        printf( "newNode data: %s\n", newNode->data);
        free( newNode );
        if( newNode->last ) done = 1;
    }

    pthread_exit( 0 );
} // end function: process_job


struct node *getNode()
{
    pthread_mutex_lock( &jobsMutex );
    if( !jobsList )
    {
        pthread_mutex_unlock( &jobsMutex );
        return NULL;
    }

    struct node *current = NULL;

    current = jobsList;
    jobsList = jobsList->next;

    pthread_mutex_unlock( &jobsMutex );
    return current;
} // end function: getNode

上面的代码产生以下输出:

代码语言:javascript
复制
newNode data: this is node:  1
newNode data: this is node:  2
newNode data: this is node:  3
newNode data: this is node:  4
newNode data: this is node:  5
newNode data: this is node:  6
newNode data: this is node:  7
newNode data: this is node:  8
newNode data: this is node:  9
newNode data: this is node:  10
newNode data: this is node:  11
newNode data: this is node:  12
newNode data: this is node:  13
newNode data: this is node:  14
newNode data: this is node:  15
newNode data: this is node:  16
newNode data: this is node:  17
newNode data: this is node:  18
newNode data: this is node:  19
newNode data: this is node:  20
newNode data: this is node:  21
newNode data: this is node:  22
newNode data: this is node:  23
newNode data: this is node:  24
newNode data: this is node:  25

您可以轻松地修改特定struct定义的代码、生成结构实例的方法、在线程中接收结构时处理结构的方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34020412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档