精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
可以在启动一个线程时设置线程的属性,或在线程运行的时候更改这些属性。常见的线程属性:
优先级系统分配的运行时间
堆栈空间影响到线程可以调用的函数数量
名字我们可以根据线程的名字,来 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;
}