如何在C语言中利用thread_create()创建一个线程-创新互联

本篇文章给大家分享的是有关如何在C语言中利用thread_create()创建一个线程,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

十余年的元谋网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都全网营销的优势是能够根据用户设备显示端的尺寸不同,自动调整元谋建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“元谋网站设计”,“元谋网站推广”以来,每个客户项目都认真落实执行。

在头文件 threads.h 中,定义和声明了支持多线程的宏、类型和函数。所有直接与线程相关的标识符,均以前缀 thrd_ 作为开头。例如,thrd_t 是一个对象类型,它标识了一个线程。

函数 thrd_create()用于创建并开始执行一个新线程。函数 thrd_create()的其中一个参数为在新线程中需要被执行的函数 thrd_create()的其中一个参数为在新线程中需要被执行的函数。thrd_create()的完整原型是:


int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);

参数 func 是一个指针,它指向在新线程需要被执行的函数,而 void 指针 arg 用于向该函数传递参数。换句话说,新线程将执行函数调用 func(arg)。

参数 func 的类型为 thrd_start_t,它被定义为 int(*)(void*)(这是一个函数指针,指向一个 void 指针作为其参数并返回一个 int 值的函数),因此,该线程执行的函数返回一个 int 类型的值。

程序在后续过程中可以通过调用函数 thread_join()获得这个 int 类型的返回值(必要时,需等待该线程执行完)。

如果一个线程启动成功,函数 thread_create()将新线程写入一个对象进行标识,并通过参数 thr 指向该对象,然后返回宏值 thread_success。

在大多数情况下,后续的其他操作均依赖于该线程的执行结果,并且只有当该线程完成后,才能执行其他操作。函数 thread_join()用于确保一个线程已完成。它的原型是:


int thrd_join(thrd_t thr, int *result);

调用 thread_join()的线程会被阻塞,直到通过 thr 标识的线程执行完成,这里“阻塞”(block)指的是:线程会在调用 thread_join()的位置停留必要的时间。然后,thread_join()将线程 thr 中执行函数的返回值写入指针 result 所引用的 int 变量中,假设 result 不是一个空指针。最后,thread_join()释放属于线程 thr 的所有资源。

如果程序逻辑上并不需要等待线程 thr 结束,则应该调用以下函数:


int thrd_detach(thrd_t thr);

thrd_detach()使得当线程 thr 执行完成后,自动释放线程占用的所有资源。一旦一个线程执行了分离操作(调用 thrd_detach()),将不用程序等待其结束,程序也不会获得该线程执行函数的返回值。对于每个创建的线程,调用 thread_join()或 thread_detach()不得超过一次。

在例 1 中的程序展示了使用并行操作处理数组的一种方式。各个线程先自行处理数组的各部分,然后将它们的处理结果组合在一起。该程序仅需计算一个数字序列的总和。

函数 sum()首先根据创建线程的较大数量确定划分数组所得的各组元素的较大数量,然后调用递归辅助函数 parallel_sum()。

函数 parallel_sum()将数组平均分为两半,将其中的一半交给一个新线程处理,同时调用自身来处理另一半数组。如该例所示,一个线程函数需要多个参数,这些参数通常采用结构进行封装。

【例1】在几个并行线程中计算数组元素的和


#include 
#include 
#define MAX_THREADS 8      // 1、2、4、8……所创建线程数量的较大值
#define MIN_BLOCK_SIZE 100   // 一个数组块的最小值
typedef struct         // 函数parallel_sum()的参数
{
  float *start;    // 传递给parallel_sum()的数组块的起始地址
  int len;      // 数组块长度
  int block_size;   // 最小数组块的大小
  double sum;         // 求和结果
} Sum_arg;
int parallel_sum(void *arg);  // 线程函数的原型
// ---------------------------------------------------------------
// 计算数组元素的和,并写入*sumPtr
// sum()调用函数parallel_sum()进行并行处理
// 返回值:如果没有发生错误,则返回true;否则,返回false
bool sum(float arr[], int len, double* sumPtr)
{
  int block_size = len / MAX_THREADS;
  if (block_size < MIN_BLOCK_SIZE) block_size = len;
  Sum_arg args = { arr, len, block_size, 0.0 };
  if (parallel_sum(&args))
  { *sumPtr = args.sum; return true; }
  else
    return false;
}
// ---------------------------------------------------------------
// 递归辅助函数,用以将工作分解到几个线程中处理
int parallel_sum(void *arg)
{
  Sum_arg *argp = (Sum_arg*)arg;       // 指向参数的指针
  if (argp->len <= argp->block_size)         // 如果length <= block_size,
                            // 对所有元素求和
  {                                 
    for (int i = 0; i < argp->len; ++i)
      argp->sum += argp->start[i];
    return 1;
  }
  else                        // 如果length > block_size,
                            // 分解数组
  {                                      
    int mid = argp->len / 2;
    Sum_arg arg2 = { argp->start+mid, argp->len-mid,
             argp->block_size, 0};    // 指定后一半数组
    argp->len = mid;           // 前一半数组的长度
    thrd_t th;               // 在新线程中处理前一半数组
    int res = 0;
    if (thrd_create(&th, parallel_sum, arg) != thrd_success)
      return 0;              // 没能成功创建新线程
    if (!parallel_sum(&arg2))  // 在当前线程下,以递归方式处理后一半数组
    {
      thrd_detach(th); return 0;     // 递归调用失败
    }
    thrd_join(th, &res);
    if (!res)
      return 0;      // 同级线程报告执行失败
    argp->sum += arg2.sum;
    return 1; 
  }
}

以上就是如何在C语言中利用thread_create()创建一个线程,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。


当前文章:如何在C语言中利用thread_create()创建一个线程-创新互联
文章地址:http://pwwzsj.com/article/dsgddd.html