线程创建
函数原型:intpthread_create(pthread_trestrict tidp,const pthread_attr_t restrict attr,void (start_rtn)(void),void restrict arg);
返回值:若是成功建立线程返回0,否则返回错误的编号。
形式参数:pthread_trestrict tidp要创建的线程的线程id指针;const pthread_attr_t restrict attr创建线程时的线程属性;void (start_rtn)(void)返回值是void类型的指针函数;void restrict arg start_rtn的形参。
线程挂起:该函数的作用使得当前线程挂起,等待另一个线程返回才继续执行。也就是说当程序运行到这个地方时,程序会先停止,然后等线程id为thread的这个线程返回,然后程序才会断续执行。
函数原型:intpthread_join(pthread_tthread, void value_ptr);
参数说明如下:thread等待退出线程的线程号;value_ptr退出线程的返回值。
返回值:若成功,则返回0;若失败,则返回错误号。
线程退出
函数原型:voidpthread_exit(void rval_ptr);
获取当前线程id
函数原型:pthread_tpthread_self(void);
互斥锁
创建pthread_mutex_init;销毁pthread_mutex_destroy;加锁pthread_mutex_lock;解锁pthread_mutex_unlock。
条件锁
创建pthread_cond_init;销毁pthread_cond_destroy;触发pthread_cond_signal;广播pthread_cond_broadcast;等待pthread_cond_wait。
rt_thread_t和rt_thread都是RT-Thread Kernel中的数据类型,它们之间的区别如下:
1 rt_thread_t是线程句柄类型,用于表示一个线程的句柄,线程句柄可以被线程调度器用来选取和调度线程,因此它是线程的唯一标识符。而rt_thread是线程的结构体,用于表示一个线程的具体信息,包括线程的优先级、栈大小、运行时间片等信息。
2 rt_thread_t是一个32位的无符号整数类型,用于表示线程的句柄,它的取值范围为0~。而rt_thread是一个自定义的结构体类型,定义在rt_threadh文件中,用于表示一个线程的具体信息。
3 在RT-Thread Kernel中,线程的 *** 作通常是通过线程句柄来完成的,例如创建线程、等待线程结束、获取线程信息等 *** 作,都需要使用线程句柄。而线程的详细信息,例如优先级、栈大小、运行时间片等,则需要通过线程结构体rt_thread来获取。
文章框架
线程开启方式
--1通过异步委托实现线程
----11定义线程
----12检测委托线程结束,通过while循环,等待句柄,函数回调
--2通过thread类开启线程
----21定义线程
----22如何传递参数
----23线程优先级
----24线程控制
--3、通过线程池开启线程
--4、通过任务开启线程
----41通过任务或任务工厂
----42连续任务
----43任务的层次结构
----44任务的执行结果
调用线程控制方法启动:ThreadStart();停止:ThreadAbort();暂停:ThreadSuspend();继续:ThreadResume();
值得注意的是: 通过 ThreadAbort() 停下来的线程(或自行运行结束的线程),都无法直接通过 ThreadStart() 方法再次启动,必须重新创建一个线程启动。
注意:线程池中的线程都是后台线程,不能修改为前台线程,不能设置优先级
如果一个任务的执行依赖于另一个任务,即任务的执行有先后顺序。此时,我们可以使用连续任务。
taskContinueWith(ReadNews)表示一个任务task结束后,才开始执行另一个任务。
在一个任务中可以启动子任务,两个任务异步执行。默认情况下,子任务(即由外部任务创建的内部任务)将独立于其父任务执行。使用TaskCreationOptionsAttachedToParent显式指定将任务附加到任务层次结构中的某个父级。
如果父任务执行完了但是子任务没有执行完,则父任务的状态会被设置为WaitingForChildrenToComplete,只有子任务也执行完了,父任务的状态才会变成RunToCompletion。
使用Task的泛型版本,可以返回任务的执行结果。
下面例子中的TaskWithResult的输入为object类型,返回一个元组Tuple<int, int>。
定义调用TaskWithResult的任务时,使用泛型类Task<Tuple<int, int>>,泛型的参数定义了返回类型。通过构造函数,传递TaskWithResult,构造函数的第二个参数定义了TaskWithResult的输入值。
任务完成后,通过Result属性获取任务的结果。
上一节中,我们探究了OC中重要的实现多线程的方法——NSOperation。本节中,我们了解一下不常用的一种创建多线程的方式——pThread。
相关链接:
NSOpreation链接: iOS详解多线程(实现篇——NSOperation)
GCD链接: iOS详解多线程(实现篇——GCD)
NSThread链接: 详解多线程(实现篇——NSThread)
多线程概念篇链接: 详解多线程(概念篇——进程、线程以及多线程原理)
源码链接: >
#ifndef THREAD_H_
#define THREAD_H_
#include <unistdh>
#include <pthreadh>
class Runnable
{
public:
//运行实体
virtual void run() = 0;
};
//线程类
class Thread: public Runnable
{
private:
//线程初始化号
static int thread_init_number;
//当前线程初始化序号
int current_thread_init_number;
//线程体
Runnable target;
//当前线程的线程ID
pthread_t tid;
//线程的状态
int thread_status;
//线程属性
pthread_attr_t attr;
//线程优先级
sched_param param;
//获取执行方法的指针
static void run0(void pVoid);
//内部执行方法
void run1();
//获取线程序号
static int get_next_thread_num();
public:
//线程的状态-新建
static const int THREAD_STATUS_NEW = 0;
//线程的状态-正在运行
static const int THREAD_STATUS_RUNNING = 1;
//线程的状态-运行结束
static const int THREAD_STATUS_EXIT = -1;
//构造函数
Thread();
//构造函数
Thread(Runnable target);
//析构
~Thread();
//线程的运行体
void run();
//开始执行线程
bool start();
//获取线程状态
int get_state();
//等待线程直至退出
void join();
//等待线程退出或者超时
void join(unsigned long millis_time);
//比较两个线程时候相同,通过current_thread_init_number判断
bool operator ==(const Thread other_pthread);
//获取this线程ID
pthread_t get_thread_id();
//获取当前线程ID
static pthread_t get_current_thread_id();
//当前线程是否和某个线程相等,通过tid判断
static bool is_equals(Thread iTarget);
//设置线程的类型:绑定/非绑定
void set_thread_scope(bool isSystem);
//获取线程的类型:绑定/非绑定
bool get_thread_scope();
//设置线程的优先级,1-99,其中99为实时,意外的为普通
void set_thread_priority(int priority);
//获取线程的优先级
int get_thread_priority();
};
int Thread::thread_init_number = 1;
inline int Thread::get_next_thread_num()
{
return thread_init_number++;
}
void Thread::run0(void pVoid)
{
Thread p = (Thread) pVoid;
p->run1();
return p;
}
void Thread::run1()
{
thread_status = THREAD_STATUS_RUNNING;
tid = pthread_self();
run();
thread_status = THREAD_STATUS_EXIT;
tid = 0;
pthread_exit(NULL);
}
void Thread::run()
{
if (target != NULL)
{
(target)run();
}
}
Thread::Thread()
{
tid = 0;
thread_status = THREAD_STATUS_NEW;
current_thread_init_number = get_next_thread_num();
pthread_attr_init(&attr);
}
Thread::Thread(Runnable iTarget)
{
target = iTarget;
tid = 0;
thread_status = THREAD_STATUS_NEW;
current_thread_init_number = get_next_thread_num();
pthread_attr_init(&attr);
}
Thread::~Thread()
{
pthread_attr_destroy(&attr);
}
bool Thread::start()
{
return pthread_create(&tid, &attr, run0, this);
}
inline pthread_t Thread::get_current_thread_id()
{
return pthread_self();
}
inline pthread_t Thread::get_thread_id()
{
return tid;
}
inline int Thread::get_state()
{
return thread_status;
}
void Thread::join()
{
if (tid > 0)
{
pthread_join(tid,NULL);
}
}
void Thread::join(unsigned long millis_time)
{
if (tid == 0)
{
return;
}
if (millis_time == 0)
{
join();
}
else
{
unsigned long k = 0;
while (thread_status != THREAD_STATUS_EXIT && k <= millis_time)
{
usleep(100);
k++;
}
}
}
bool Thread::operator ==(const Thread other_pthread)
{
if(other_pthread==NULL)
{
return false;
}if(current_thread_init_number==(other_pthread)current_thread_init_number)
{
return true;
}
return false;
}
bool Thread::is_equals(Thread iTarget)
{
if (iTarget == NULL)
{
return false;
}
return pthread_self() == iTarget->tid;
}
void Thread::set_thread_scope(bool isSystem)
{
if (isSystem)
{
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
}
else
{
pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS);
}
}
void Thread::set_thread_priority(int priority)
{
pthread_attr_getschedparam(&attr,¶m);
param__sched_priority = priority;
pthread_attr_setschedparam(&attr,¶m);
}
int Thread::get_thread_priority(){
pthread_attr_getschedparam(&attr,¶m);
return param__sched_priority;
}
#endif / THREAD_H_ /
编译时要用到pthread 库:gcc -lpthread
错误码位置:/usr/include/asm-generic/errnoh
gcc pthread_createc -lpthread
思考:主子线程交替打印奇数偶数。
思考:证明线程可以自己取消自己。
思考:证明SIGKILL和SIGSTOP 是无法阻塞的。
/usr/include/bits/pthreadtypesh中查看pthread_mutex_t
思考:用多线程将一个文件1c拷贝3个副本,11c,12c,13c
思考:多个生产者和消费者
思考:将互斥量等初始化使用pthread_once实现。
思考:设置线程的分离属性,然后在新县城中获取自己的分离属性。
以上就是关于C语言多线程的 *** 作步骤全部的内容,包括:C语言多线程的 *** 作步骤、rt_thread_t和rt_thread区别、线程开启的四种方式(异步委托,thread类,线程池,任务)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)