C语言多线程的 *** 作步骤

C语言多线程的 *** 作步骤,第1张

线程创建

函数原型: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,&param);  

param__sched_priority = priority;  

pthread_attr_setschedparam(&attr,&param);  

}  

int Thread::get_thread_priority(){  

pthread_attr_getschedparam(&attr,&param);  

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类,线程池,任务)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9555662.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存