锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / 线程属性、启动线程、结束线程
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

线程属性、启动线程、结束线程

线程的属性

可以在启动一个线程时设置线程的属性,或在线程运行的时候更改这些属性。常见的线程属性:

优先级

系统分配的运行时间

堆栈空间

影响到线程可以调用的函数数量

名字

我们可以根据线程的名字,来 DEBUG 或是TRACK 这个运行中的线程

线程组

我们可以通过线程组,来管理同一时间运行的多个线程

Detach state

这个状态标识了当线程结束时,我们如何回收,或保留这个线程使用过的资源

任务计划

线程在系统或在应用中是如何被安排、计划的。

继承

判断线程的属性是否继承

更改线程的属性,可以使用系统API 函数,如pthread_attr_setdetachstate()函数就可以更改detach state 这个属性,详见Pthread_attr_setdetachstate()

更改线程属性后,再启动的线程就将具备更改后的属性,见下例:

   #define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define checkResults(string, val) { \
if (val) { \
printf("Failed with %d at %s", val, string); \
exit(1); \
} \
}
void *theThread(void *parm)
{
printf("Entered the thread\n");
return NULL;
}
int main(int argc, char **argv)
{
pthread_attr_t attr;
pthread_t thread;
int rc=0;
printf("Enter Testcase - %s\n", argv[0]);
printf("Create a default thread attributes object\n");
rc = pthread_attr_init(&attr);
checkResults("pthread_attr_init()\n", rc);
printf("Set the detach state thread attribute\n");
rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
checkResults("pthread_attr_setdetachstate()\n", rc);
printf("Create a thread using the new attributes\n");
rc = pthread_create(&thread, &attr, theThread, NULL);
checkResults("pthread_create()\n", rc);
printf("Destroy thread attributes object\n");
rc = pthread_attr_destroy(&attr);
checkResults("pthread_attr_destroy()\n", rc);
printf("Join now fails because the detach state attribute was changed\n");
rc = pthread_join(thread, NULL);
if (rc==0) {
printf("Unexpected results from pthread_join()\n");
exit(1);
}
sleep(2);
printf("Main completed\n");
return 0;
}

启动线程

当我们的应用程序创建了一个线程的时候,系统将会对线程的属性、控制结构、和运行时间等内容进行初始化,以保证线程安全的运行。

当然,启动一个线程的时候,我们也需要在应用程序中对该线程可能使用到的的数据和输入输出参数进行初始化。

启动一个线程后,系统将会为这个线程分配一个唯一的线程标识号。线程标识号是一个整型变量,我们可以通过这个线程标识号,来对该线程进行DEBUG,TRACE,或其它类型的管理操作。但是不能通过线程标识号直接操作或控制这个线程。

大部分线程的 API 函数都会返回线程描述符,我们可以通过返回的线程描述符对线程进行直接操作,也可能通过一些同步机制等待线程结束处理。

下面的例子中,主程序启动了一个线程,并向这个线程传递了两个参数,一个是整型变量,一个是124 位长的字符型变量。参数做为一个全局变量来定义。

启动的线程不仅打印了主程序传递过来的参数,而且还使用了 pthread_getthreadid_np()函数取出自身的线程标识号,注意该函数的输出是一个pthread_id_np_t 类型的结构(其实 该结构里面也就是hi,lo 两个整型变量)

这里主要用到的,就是 pthread_create()这个函数,函数说明详见pthread_create()

   #define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define checkResults(string, val) { \
if (val) { \
printf("Failed with %d at %s", val, string); \
exit(1); \
} \
}
typedef struct {
int threadParm1;
char threadParm2[124];
} threadParm_t;
void *theThread(void *parm)
{
pthread_id_np_t tid;
threadParm_t *p = (threadParm_t *)parm;
tid = pthread_getthreadid_np();
printf("Thread ID %.8x, Parameters: %d is the answer to \"%s\"\n",
tid.intId.lo, p->threadParm1, p->threadParm2);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thread;
int rc=0;
threadParm_t *threadParm;
printf("Enter Testcase - %s\n", argv[0]);
threadParm = (threadParm_t *)malloc(sizeof(threadParm));
threadParm->threadParm1 = 42;
strcpy(threadParm->threadParm2, "Life, the Universe and Everything");
printf("Create/start a thread with parameters\n");
rc = pthread_create(&thread, NULL, theThread, threadParm);
checkResults("pthread_create()\n", rc);
printf("Wait for the thread to complete\n");
rc = pthread_join(thread, NULL);
checkResults("pthread_join()\n", rc);
printf("Main completed\n");
return 0;
}

结束线程

结束线程通常是由该线程自身发起的。

当一个线程完成了所有的处理之后,它将会有一个关闭自身的动作,释放系统资源以便之后其它的线程使用这些资源。

有些 API 函数要求应用程序在程序结束时,明确地给出释放资源的语句。也有些线程的处理机制没有这样要求(如JAVA)。

可以有多种方法去结束一个线程。最好的方法就是return 到创建这个线程的程序中。因为有关线程的API 函数。

有些 API 函数也支持exception 机制。这里所说的Exception 机制,是指当发生一个一个exception 而且没有去处理它的时候,线程将会结束。

下面的例子中,主要是在线程调用的函数中使用的 pthread_exit()函数来结束掉辅线程,以及初始线程中使用的pthread_join()接收辅线程中的返回。

   #define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define checkResults(string, val) { \
if (val) { \
printf("Failed with %d at %s", val, string); \
exit(1); \
} \
}
const int THREADFAIL = 1;
const int THREADPASS = 0;
void *theThread(void *parm)
{
printf("Thread: End with success\n");
pthread_exit(__VOID(THREADPASS));
printf("Thread: Did not expect to get here!\n");
return __VOID(THREADFAIL);
}
int main(int argc, char **argv)
{
pthread_t thread;
int rc=0;
void *status;
printf("Enter Testcase - %s\n", argv[0]);
printf("Create/start a thread\n");
rc = pthread_create(&thread, NULL, theThread, NULL);
checkResults("pthread_create()\n", rc);
printf("Wait for the thread to complete, and release its resources\n");
rc = pthread_join(thread, &status);
checkResults("pthread_join()\n", rc);
printf("Check the thread status\n");
if (__INT(status) != THREADPASS) {
printf("The thread failed\n");
}
printf("Main completed\n");
return 0;
}
友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内