以下代码运行多个线程,如果已经使用相同的ID启动了一个线程,它将取消之前的线程。我使用此代码重新启动灯的计时器。
我的问题是如何重复使用两次线程参数?我必须为struct" thread_data"分配内存。在重用之前和再次创建线程之前...这可以通过" thread_list"来完成。地图?也许我没有问正确的问题......但是,我正确回答
#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;
}
答案 0 :(得分:0)
首先,您似乎正在尝试使用不为其分配内存的结构:
thread_data td;
td.time = time;
td.num = "Ok";
这个代码片段在我看来是错误的,因为没有为变量td
分配内存(堆栈除外),但它尝试分配一个值。因此,一旦创建了线程并且函数返回,则内存将被破坏。因此,您永远不应该使用局部变量将数据传递给另一个函数。通常,我希望为结构分配一些堆内存,例如:
thread_data td;
td = malloc( sizeof( thread_data ) );
if( td == NULL ) ... [error handling] ...
td.time = time;
td.num = "Ok";
每次需要此结构时,都应为其分配内存。通常,(除了在专门的高性能应用程序中),您不应该尝试重新使用内存。
另外,请注意设计存在缺陷,因为无法释放为td
结构分配的内存。你应该在更高级别创建td结构,例如,在main()中,然后当interrupt()函数返回时,你应该释放使用的内存。例如:
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 );
或类似的东西。
答案 1 :(得分:0)
我在“thread_data”结构中设置了“td”。很长一段时间后它失败了......
struct thread_data
{
int duration;
string num;
string type;
} td;
完成代码:
#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;
}