您的位置:首页 > 其它

[POSIX线程模型]_[使用pthread对工作线程进行简单控制-暂停-继续-停止]

2014-07-16 15:21 543 查看
1.使用命令行对线程简单控制。

界面和Win32版本的:

/article/7711751.html

场景:

1.在开发界面程序时,为了不让界面程序挂起,会新建一个工作线程来处理逻辑,主线程就能持续和用户交互。

2.pthread优点:跨平台。

耗时:3h

文件1: test_pthread.cpp

[cpp]
view plaincopy

#include <stdio.h>
#include "pthread.h"
#include <iostream>

using namespace std;

enum DhThreadStatus
{
kStop,
kRunning,
kPause
};

typedef struct DhThreadData
{
int thread_status;

pthread_mutex_t mutex;//共享互斥量

//1.控制工作线程.
pthread_cond_t work_cond;//条件变量

//1.控制主线程.
pthread_cond_t main_cond;//条件变量

FILE* file;//记录日志

}DhThreadData;

void WriteLine(const char* str,FILE* file,bool is_print_console = true)
{
if(is_print_console)
{
printf("%s",str);
}
size_t log_length = strlen(str);
fwrite(str,log_length,1,file);
fflush(file);
}

void StopThread(DhThreadData* thread_data)
{
//call stop
//如果是扫描或暂停状态,通知线程停止扫描.
//等待线程结束.
pthread_mutex_lock(&thread_data->mutex);
thread_data->thread_status = kStop;
pthread_cond_signal(&thread_data->work_cond);//1.告诉工作线程可以继续了.
pthread_cond_wait(&thread_data->main_cond,&thread_data->mutex);//2.等待
pthread_mutex_unlock(&thread_data->mutex);
WriteLine("Continue response key press.\n",thread_data->file);

}

void * StartPthread(void * arg)
{
DhThreadData* data = (DhThreadData*)arg;
WriteLine("StartPthread begin scan.\n",data->file);

data->thread_status = kRunning;
while(true)
{
WriteLine("StartPthread scanning.\n",data->file,false);
//1.暂停
if(data->thread_status == kPause)
{
WriteLine("StartPthread pause thread.\n",data->file);
pthread_mutex_lock(&data->mutex);
pthread_cond_signal(&data->main_cond);
pthread_cond_wait(&data->work_cond,&data->mutex);
pthread_mutex_unlock(&data->mutex);
//1.返回时,状态是kRunning或者kStop.
if(data->thread_status == kRunning)
{
//1.告诉主线程继续.
WriteLine("StartPthread continue thread.\n",data->file);
pthread_cond_signal(&data->main_cond);
}
}
if(data->thread_status == kStop)
{
pthread_mutex_lock(&data->mutex);
pthread_cond_signal(&data->main_cond);
pthread_mutex_unlock(&data->mutex);
WriteLine("StartPthread Stop.\n",data->file);
break;
}
Sleep(500);
}
//1.告诉主线程继续,工作线程已结束.
return NULL;
}

void StartScan(DhThreadData* data)
{
pthread_t t1;
pthread_create(&t1, NULL, StartPthread, data);
pthread_detach(t1);
}

int main(int argc, char *argv[])
{
setbuf(stdout, (char*) 0);
setbuf(stderr, (char*) 0);
FILE* file = fopen("log.txt","w");
WriteLine("begin........\n",file);

DhThreadData thread_data;
memset(&thread_data,0,sizeof(thread_data));
thread_data.file = file;
pthread_mutex_init(&thread_data.mutex,NULL);
pthread_cond_init(&thread_data.work_cond,NULL);

pthread_cond_init(&thread_data.main_cond,NULL);

int i;
WriteLine("1.开始扫描.\n2.继续扫描->暂停扫描切换.\n3.停止扫描.\nEnter q for exit:.\n",file);
while(1)
{
i = getchar();
if(i == '\n')
{
continue;
}

if(i == 'q')
{
if(thread_data.thread_status != kStop)
{
StopThread(&thread_data);
}
WriteLine("Exit.\n",file);
break;
}else if(i == '1')
{
if(thread_data.thread_status == kStop)
{
StartScan(&thread_data);
}else
{
WriteLine("Scanning.\n",file);
WriteLine("Continue response key press.\n",file);
continue;
}
}else if(i == '2')
{
if(thread_data.thread_status == kStop)
{
WriteLine("Press 1 for begin scanning.\n",file);
WriteLine("Continue response key press.\n",file);
continue;
}
//如果是暂停状态,通知线程继续扫描.
if(thread_data.thread_status == kPause)
{
//继续
pthread_mutex_lock(&thread_data.mutex);
thread_data.thread_status = kRunning;
pthread_cond_signal(&thread_data.work_cond);//1.告诉工作线程可以继续了.
pthread_cond_wait(&thread_data.main_cond,&thread_data.mutex);//2.等待
pthread_mutex_unlock(&thread_data.mutex);
}else
{
//暂停
pthread_mutex_lock(&thread_data.mutex);
thread_data.thread_status = kPause;
pthread_cond_wait(&thread_data.main_cond,&thread_data.mutex);
pthread_mutex_unlock(&thread_data.mutex);

}
WriteLine("Continue response key press.\n",file);
continue;
}else if (i == '3')
{
if(thread_data.thread_status == kStop)
{
WriteLine("Scan has stopped.\n",file);
WriteLine("Continue response key press.\n",file);
continue;
}
StopThread(&thread_data);
}
}

pthread_mutex_destroy(&thread_data.mutex);
pthread_cond_destroy(&thread_data.work_cond);

pthread_cond_destroy(&thread_data.main_cond);
fclose(file);
WriteLine("end...........\n",file);
return 0;
}

输出:

[plain]
view plaincopy

begin........
1.开始扫描.
2.继续扫描->暂停扫描切换.
3.停止扫描.
Enter q for exit:.
StartPthread begin scan. //1
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread pause thread. //2
Continue response key press.
StartPthread continue thread. //2
Continue response key press.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread pause thread. //2
Continue response key press.
StartPthread continue thread. //2
Continue response key press.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread Stop. //3
Continue response key press.
StartPthread begin scan. //1
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread pause thread. //2
Continue response key press.
StartPthread Stop. //3
Continue response key press.
StartPthread begin scan. //1
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread Stop. //3
Continue response key press.
StartPthread begin scan. //1
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread scanning.
StartPthread Stop. //q
Continue response key press.
Exit.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: