简体   繁体   English

将结构内存分配给多个线程的args

[英]Allocate struct memory to args for multiple thread

The following code runs mutiple threads and if a thread is already launched with the same id, it cancels the previous thread. 以下代码运行多个线程,并且如果已经使用相同的ID启动了一个线程,它将取消前一个线程。 I use this code to relaunch a timer for a light. 我使用此代码重新启动计时器。

My problem is how to reuse thread params twice ? 我的问题是如何重用线程参数两次? I must allocate memory for the struct "thread_data" before reuse and before create thread again... This can be done with through the "thread_list" map ? 在重用之前和再次创建线程之前,我必须为结构“ thread_data”分配内存。这可以通过“ thread_list”映射来完成吗? Maybe I'm not asking the right question... However I'm sur right answer 也许我不是在问正确的问题...但是我是正确的答案

#include <iostream>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#include <map>

using namespace std;

pthread_mutex_t mutex_t;
map <string, pthread_t> thread_list;

struct thread_data
{
    char *num;
    char *type;
    int time;
};

static void cleanup(void *arg)
{
    pthread_mutex_lock(&mutex_t);
    cout << "Thread Cleaned" << endl;
    pthread_mutex_unlock(&mutex_t);
}

static void *thread(void *arg)
{
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);

    pthread_cleanup_push(&cleanup,NULL);

    thread_data* my_data = (thread_data*)(arg);
    int time = my_data->time;

    pthread_mutex_lock(&mutex_t);
    cout << "Thread start " << time << " " << my_data->num << endl << flush;
    pthread_mutex_unlock(&mutex_t);

    while(time)
    {
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
        pthread_testcancel();
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);

        sched_yield();

        pthread_mutex_lock(&mutex_t);
        sleep(1);
        time--;
        pthread_mutex_unlock(&mutex_t);
    }

    pthread_mutex_lock(&mutex_t);
    cout << "Thread End " << endl;
    pthread_mutex_unlock(&mutex_t);

    pthread_cleanup_pop(0);

    return NULL;
}

void interrupt(string num, int time = 0, string type = "")
{
    cout << "Interruptable " << num << " " << time << " " << type << endl;

    if (thread_list.find(num)->second)
    {
        cout << "Cancel " << num << endl;

        if (pthread_cancel(thread_list[num]) == 0)
        {
            pthread_detach(thread_list[num]);
            while (pthread_kill(thread_list[num], 0)==0)
                sched_yield();
        }

        thread_list.erase(num);
    }

    thread_data td;
    td.time = time;
    td.num = "Ok";

    pthread_t thread_id;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    pthread_mutex_init(&mutex_t, NULL);
    pthread_create (&thread_id, &attr, &(thread), (void *)&td);
    thread_list.insert(pair <string, pthread_t> (num, thread_id));
}

int main()
{
    cout << "Start main" << endl;

    interrupt("6335", 5, "");
    sleep(1);
    interrupt("6335", 2, "");
    sleep(6);

    cout << "End main" << endl;
    return 0;
}

First of all, it appears you are trying to use a structure without allocating memory for it: 首先,看来您正在尝试使用一种结构而不为其分配内存:

 thread_data td;
 td.time = time;
 td.num = "Ok";

This code fragment would appear to me to be in error because no memory is assigned to the variable td (except the stack), yet it attempts to assign a value. 在我看来,这段代码片段是错误的,因为没有将内存分配给变量td (堆栈除外),但是它试图分配一个值。 Thus, once the thread is created and the function returns the memory will be corrupted. 因此,一旦创建线程并返回函数,内存将被破坏。 For this reason you should never use a local variable for passing data to another function. 因此,永远不要使用局部变量将数据传递给另一个函数。 Normally, I would expect the structure to be allocated some heap memory, for example: 通常,我希望为该结构分配一些堆内存,例如:

 thread_data td;
 td = malloc( sizeof( thread_data ) );
 if( td == NULL ) ... [error handling] ...
 td.time = time;
 td.num = "Ok";

Each time you need this structure you should allocate memory for it. 每次需要此结构时,都应为其分配内存。 Normally, (except in a specialized high-performance application) you should not attempt to re-use the memory. 通常,(除非在专用的高性能应用程序中)您不应尝试重新使用内存。

Also, note that the design is flawed because there is no way to free the memory allocated for the td structure. 另外,请注意该设计存在缺陷,因为无法释放为td结构分配的内存。 You should actually create the td structure at a higher level, for example, in main(), then when the interrupt() function returns you should free the memory used. 实际上,您应该在更高级别上创建td结构,例如在main()中,然后在interrupt()函数返回时,应释放所使用的内存。 For example: 例如:

   main(){
     ....
     thread_data td;
     td = malloc( sizeof( thread_data ) );
     if( td == NULL ) ... [error handling] ...
     td.time = time;
     td.num = "Ok";
     interrupt( td );
     ...
     [do next interrupt]
     ...
     [after worker thread is complete]
     free( td );

or something along those lines. 或类似的规定。

I set "td" in "thread_data" structure. 我在“ thread_data”结构中设置了“ td”。 It fails after a long time.... 很长一段时间后失败了...

struct thread_data
{
    int duration;
    string num;
    string type;
} td;

Complet code : 完成代码:

#include <iostream>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#include <map>

using namespace std;

pthread_mutex_t mutex_t;
map <string, pthread_t> thread_list;

struct thread_data
{
    int duration;
    string num;
    string type;
} td;

static void cleanup(void *arg)
{
    pthread_mutex_lock(&mutex_t);
    cout << "Thread Cleaned" << endl;
    pthread_mutex_unlock(&mutex_t);
}

static void *thread(void *arg)
{
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);

    pthread_cleanup_push(&cleanup,NULL);

    thread_data* my_data = (thread_data*)(arg);
    int duration = my_data->duration;

    pthread_mutex_lock(&mutex_t);
    cout << "Thread start " << duration << " " << my_data->num << endl;
    pthread_mutex_unlock(&mutex_t);

    while(duration)
    {
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
        pthread_testcancel();
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);

        sched_yield();

        pthread_mutex_lock(&mutex_t);
        sleep(1);
        duration--;
        pthread_mutex_unlock(&mutex_t);
    }

    pthread_mutex_lock(&mutex_t);
    cout << "Thread End " << endl;
    pthread_mutex_unlock(&mutex_t);

    pthread_cleanup_pop(0);

    return NULL;
}

void timer_launch(int duration, string num, string type)
{
    cout << "Interruptable " << num << " " << duration << " " << type << endl;

    if (thread_list.find(num)->second)
    {
        cout << "Cancel " << num << endl;

        if (pthread_cancel(thread_list[num]) == 0)
        {
            pthread_detach(thread_list[num]);
            while (pthread_kill(thread_list[num], 0)==0)
                sched_yield();
        }
        thread_list.erase(num);
    }

    td.duration = duration;
    td.num = num;
    td.type = type;

    pthread_t thread_id;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    pthread_mutex_init(&mutex_t, NULL);
    pthread_create (&thread_id, &attr, &(thread), (void *)&td);

    thread_list.insert(pair <string, pthread_t> (td.num, thread_id));
}

int main()
{
    cout << "Start main" << endl;

    timer_launch(5, "6335", "div");
    sleep(1);
    timer_launch(3, "6335", "div");
    sleep(6);

    cout << "End main" << endl;
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM