一、多线程编程常用函数用法
1、pthread_create
头文件
#include<pthread.h>
函数声明
int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg)
函数功能
pthread_create是UNIX环境创建线程函数
参数介绍
1)参数一:为指向线程标识符的指针
2)参数二:用来设置线程属性
3)参数三:是线程运行函数的起始地址
4)参数四:运行函数的参数
返回值
线程创建成功返回0,否则返回错误码
注意
在编译时注意加上-lpthread参数,以调用动态链接库,pthread并非Linux系统的默认库
2、pthread_join
头文件
#include<pthread.h>
函数声明
int pthread_join(pthread_t thread, void **retval);
函数功能
函数pthread_join用来等待一个线程的结束
函数参数
1)参数一:被等待的线程标识符
2)参数二:用户定义的指针,它可以用来存储被等待线程的返回值
函数返回值
如果执行成功,将返回0,如果失败则返回一个错误码
注意
这个函数是一个线程阻塞的函数,调用它的线程将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回
示例
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/prctl.h>
struct data {
int num;
char *name;
};
void* pthread(void *arg) {
/* 设置线程名称 */
prctl(PR_SET_NAME, "sub thread");
/* 获取线程名称 */
char threadName[30];
prctl(PR_GET_NAME, threadName);
/* pthread线程开始运行 */
printf("%s start!\n", threadName);
/* 令主线程继续执行 */
sleep(5);
/* 输出主线程传入的数据 */
struct data *p = (struct data *)arg;
printf("num is %d!\n", p->num);
printf("name is %s!\n", p->name);
return NULL;
}
void main()
{
/* 设置主线程名称 */
prctl(PR_SET_NAME, "main thread");
/* 创建pthread线程,并传入自定义数据 */
pthread_t tidp;
struct data *p = (struct data *)malloc(sizeof(struct data));
p->num = 10;
p->name = "jams";
if (pthread_create(&tidp, NULL, pthread, (void*)p) != 0) {
printf("create error!\n");
return;
}
/* 令pthread线程先运行 */
sleep(1);
/* pthread线程sleep 5s,此时主线程开始工作 */
printf("main thread continue!\n");
/* 等待pthread释放 */
if (pthread_join(tidp, NULL) != 0) {
printf("pthread_join error!\n");
return;
}
printf("pthread is end!\n");
}
3、pthread_cancel
头文件
#include<pthread.h>
函数声明
int pthread_cancel(pthread_t thread);
函数功能
终止线程的执行,多线程程序中,一个线程可以借助 pthread_cancel() 函数向另一个线程发送“终止执行”的信号(后续称“Cancel”信号),从而令目标线程结束执行。
函数参数
1)thread线程ID
函数返回值
pthread_cancel() 函数成功地发送了 Cancel 信号,返回数字 0;反之如果发送失败,函数返回值为非零数。对于因“未找到目标线程”导致的信号发送失败,函数返回ESRCH宏。
注意
pthread_cancel() 函数的功能仅仅是向目标线程发送cancel信号,至于目标线程是否处理该信号以及何时结束执行,由目标线程决定
4、pthread_kill
头文件
#include<pthread.h>
函数声明
int pthread_kill(pthread_t thread, int sig)
函数功能
向指定的线程发送信号
函数参数
1)thread目标线程
2)sig要发送的信号
函数返回值
函数调用成功返回0,失败返回非0值
注意
0是保留信号,用来判断线程是否存在
示例
int ThreadMonitorImpl::CSFRegThreadMonitor(pthread_t tid, CSF_THREAD_MONITOR_TYPE_E monitorType,
CSF_THREAD_MONITOR_CONFIG_UNION monitorConfig)
{
int isAlive = pthread_kill(tid, 0);
if (isAlive == ESRCH) {
STD_LOG(LOG_LEVEL_ERR, "CSFRegThreadMonitor, tid is invalid or thread already exit, tid is %d", tid);
return ERR_THREAD_MONITOR_TID_INVALID;
} else if (isAlive == EINVAL) {
STD_LOG(LOG_LEVEL_ERR, "CSFRegThreadMonitor, check is thread exist failed");
}
if (THREADMONITOR->threadIdStatusIndex.count(tid) > 0) { /* 任务重复时拒绝 */
std::map<CSF_THREAD_MONITOR_TYPE_E, void *> &originThreadStatus = THREADMONITOR->threadIdStatusIndex[tid];
if (originThreadStatus.count(monitorType) > 0) {
STD_LOG(LOG_LEVEL_ERR, "add thread to monitor list failed, reason: repeat reg]tid=%lu, monitorType=%d",
(unsigned long)tid, (int)monitorType);
return ERR_THREAD_MONITOR_ADD_REPEAT;
}
}