菜单

理财婆高手论坛Linux/UNIX线程(1)

2019年9月4日 - 操作系统

intpthread_detach(pthread_t thread);

intpthread_equal(pthread_t t1, pthread_t t2);

thread 1 returning

1.      线程只是从起步例程中回到,重临值是线程的退出码

thread 2 exit code 2

[cpp] view plaincopyprint?01.#include<stdio.h>  
02.#include<stdlib.h>  
03.#include<pthread.h>  
04.  
05.void * thr_fn1(void*arg) 
06.{ 
07.    printf(“thread 1 returning\n”); 
08.    return((void *)1); 
09.} 
10.  
11.void * thr_fn2(void*arg) 
12.{ 
13.    printf(“thread 2 exiting\n”); 
14.    pthread_exit((void *)2); 
15.} 
16.voiderr_quit(const char* fmt, …) 
17.{ 
18.    printf(“%s\n”,fmt); 
19.    exit(1); 
20.} 
21.int main(void) 
22.{ 
23.    int        err; 
24.    pthread_t  tid1, tid2; 
25.    void       *tret; 
26.  
27.    err = pthread_create(&tid1, NULL,thr_fn1, NULL); 
28.    if (err != 0) 
29.    { 
30.        err_quit(“can’t create thread 1:%s\n”, strerror(err)); 
31.  
32.    } 
33.    err = pthread_create(&tid2, NULL,thr_fn2, NULL); 
34.    if (err != 0) 
35.        err_quit(“can’t create thread 2:%s\n”, strerror(err)); 
36.err = pthread_join(tid1, &tret); 
37.if (err != 0) 
38.        err_quit(“can’tjoin with thread 1: %s\n”,
strerror(err)); 
39.    printf(“thread 1 exitcode %d\n”, (int)tret); 
40.    err = pthread_join(tid2,&tret); 
41.    if (err != 0) 
42.        err_quit(“can’tjoin with thread 2: %s\n”,
strerror(err)); 
43.    printf(“thread 2 exitcode %d\n”, (int)tret); 
44.    exit(0); 
45.} 
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
 
void * thr_fn1(void*arg)
{
    printf(“thread 1 returning\n”);
    return((void *)1);
}
 
void * thr_fn2(void*arg)
{
    printf(“thread 2 exiting\n”);
    pthread_exit((void *)2);
}
voiderr_quit(const char* fmt, …)
{
    printf(“%s\n”,fmt);
    exit(1);
}
int main(void)
{
    int        err;
理财婆高手论坛Linux/UNIX线程(1)。    pthread_t  tid1, tid2;
    void       *tret;
 
    err = pthread_create(&tid1, NULL,thr_fn1, NULL);
    if (err != 0)
    {
        err_quit(“can’t create thread 1:%s\n”, strerror(err));
 
    }
    err = pthread_create(&tid2, NULL,thr_fn2, NULL);
    if (err != 0)
        err_quit(“can’t create thread 2:%s\n”, strerror(err));
err = pthread_join(tid1, &tret);
if (err != 0)
        err_quit(“can’tjoin with thread 1: %s\n”, strerror(err));
    printf(“thread 1 exitcode %d\n”, (int)tret);
    err = pthread_join(tid2,&tret);
    if (err != 0)
        err_quit(“can’tjoin with thread 2: %s\n”, strerror(err));
    printf(“thread 2 exitcode %d\n”, (int)tret);
    exit(0);
}

)
本文将介绍怎样采用七个调节线程在单个进度情状中执行八个任务。
叁个进程中的全部线程都得以访谈该进程的组成都部队件(如文件…

线程(1)

重临值:若成功则重返0,不然重回错误编号。

线程能够经过调用

./a.out

#include<pthread.h>

voidpthread_cleanup_pop(int execute);

3.      线程调用pthread_exit

    pid = getpid();
    tid = pthread_self();
    printf(“%s pid %u tid %u (0x%x)\n”, s, (unsigned int)pid,
      (unsigned int)tid, (unsigned int)tid);
}

但线程能够经过下列三种办法退出:

进度ID在整个类别中是不二法门的。每种线程ID,线程ID只在它所属的历程处境中有效。

2.      线程能够被同一进程中的其余线程裁撤

主线程要求休眠,不然一切经过有相当的大希望在新线程进入运维以前就终止了。新线程是透过pthread_self()来赢得本人的线程ID,实际不是从分享内部存款和储蓄器中读出只怕从线程的启航例程中以参数接收到。pthread_create函数会通过第三个参数重返新建线程的ID。在本例中,新建线程ID被放在ntid中,可是即使新线程在主线程调用pthread_create重回在此以前就运营了,那么新线程看到的是未开始化的ntid内容。

当pthread_create成功再次回到时,由thread指向的内部存款和储蓄器单元被安装为新创立线程的线程ID。attr参数用于定制各类差异的线程属性。将attr设置为NULL,成立暗中认可属性的线程。

重返值:若成功则重回0,不然重临错误编号

线程标志

#include <pthread.h>

                          void*(*start_routine) (void *), void
*arg);

 
线程的分别景况调控二个线程以什么样的不二诀窍来终止自个儿。在暗许景况下线程是非分离状态的,这种气象下,原有的线程等待创制的线程停止。独有当pthread_join()函数重临时,成立的线程才算终止,技术假释本人攻克的系统能源。而分手线程不是那样子的,它从未被别的的线程所等待,自个儿运营甘休了,线程也就止住了,即刻释放系统能源,对分离景况的线程举行pthread_join的调用能够生出挫败,再次回到EINVAL。pthread_detach调用能够用于使线程进入分离意况。

调用pthread_join函数的线程将平素被打断,直到钦点的线程调用pthread_exit
、从运转例程中回到可能被撤销。假诺线程只是从它的运转例程再次来到,retval
将满含重临码。假设线程被撤消,retval
钦命的内部存款和储蓄器单元就安装为PTHREAD_CANCELED。

编译:

    err = pthread_create(&ntid, NULL, thr_fn, NULL);
    if (err != 0)
        err_quit(“can’t create thread: %s\n”, strerror(err));
printids(“main thread:”);
    sleep(1);
    exit(0);
}

pthread_t ntid;

 pthread 库不是 Linux 系统默许的库,连接时需求动用静态库
libpthread.a,所以在行使pthread_create()创立线程,以及调用
pthread_atfork()函数建设构造fork管理程序时,须要链接该库。

thread 1 exit code 1

intpthread_join(pthread_t thread, void **retval);

能够观察当贰个线程通过调用pthread_exit退出或简捷地从起步例程中回到时,进程中的其余线程能够经过调用pthread_join函数得到该线程的退出状态。

当线程推行以下动作时调用清理函数,调用参数为arg,清理函数routine的调用顺序是由pthread_cleanup_push函数布置的。

thread 2 push complete

3.用非零execute参数调用voidpthread_cleanup_pop时

线程能够透过调用pthread_cancel函数央求打消同一进度中的别的线程。

voidpthread_exit(void *retval);

#include<pthread.h>

 #include<pthread.h>

线程制造时并不能确定保障哪个线程会先运转:是新成立的线程仍旧调用线程。新创立的线程能够访谈进度的地点空间,並且继续调用线程的浮点意况和实信号屏蔽字,但该线程的未决复信号集被清除。

线程可以配备它退出时需求调用的函数,这与经过能够用atexit函数布署进度退出时须要调用的函数时临近的。这样的函数成为线程清理管理程序。线程能够创立多个清理程序。管理程序记录在栈中,也正是说它们的推行各样与它们注册时的相继相反。

下边包车型大巴次第创设了一个线程而且打字与印刷进度ID、新线程的线程ID以及开始化线程的线程ID。

线程包罗了代表经过内施行意况必需的新闻,在那之中囊括经过中标志线程的线程ID、一组寄放器值、栈、调解优先级和宗旨、能量信号屏蔽字、errno变量以及线程私有数据。进程的具有信息对该进度的具备线程都以共享的,包括可试行的次第文件、程序的全局内部存款和储蓄器和堆内部存储器、栈以及文件叙述符。

重返值:若相等则赶回非0值,否则重返0。

thread 1 push complete

运营及出口:

thread 2 exit code 2

借使经过中的任一线程调用了exit,_Exit或者_exit,那么万事进程就能终止。三回类似,即使复信号的暗中认可动作是结束进度,那么,把该非确定性信号发送到线程会告一段落整个经过。

thread 1 start

重临值:若成功则再次回到0,不然再次来到错误编号

线程终止

thread 2 start

voidpthread_cleanup_push(void (*routine)(void *), void *arg);

gcc creatThread.c –lpthread

线程创立
创设线程能够调用pthread_create函数成立。

正文将介绍怎样采纳四个调整线程在单个进度景况中实行多少个职责。

int pthread_cancel(pthread_t thread);

从输出结果能够见见五个线程都没有错的启航和剥离了,不过只调用了第二个线程的清理管理程序,所以假使线程是经过从它的起步例程中回到而止住的话,那么它的清理管理程序就不会被调用,还要小心清理程序是鲁人持竿与它们安装时反而的逐个被调用的。

在暗中认可情状下,pthread_cancel函数会使得由thread标记的线程的行为表现为仿佛调用了参数为PTHREAD_CANCELED的pthread_exit函数,可是线程能够挑选忽略撤废方式或是决定打消格局。

重返值是调用线程的线程。

纵然execute为0,清理函数将不被调用。无论哪一种情形,pthread_cleanup_pop都将去除上次pthread_cleanup_push调用建立的清理管理程序。

[cpp] view plaincopyprint?01.#include <stdio.h>  
02.#include <stdlib.h>  
03.#include <pthread.h>  
04.  
05.void cleanup(void *arg) 
06.{ 
07.   printf(“cleanup: %s\n”, (char *)arg); 
08.} 
09.  
10.void * thr_fn1(void *arg) 
11.{ 
12.   printf(“thread 1 start\n”); 
13.   pthread_cleanup_push(cleanup, “thread 1 first handler”); 
14.   pthread_cleanup_push(cleanup, “thread 1 second handler”); 
15.   printf(“thread 1 push complete\n”); 
16.   if (arg) 
17.       return((void *)1); 
18.   pthread_cleanup_pop(0); 
19.   pthread_cleanup_pop(0); 
20.return((void*)1); 
21.} 
22.  
23.void * thr_fn2(void *arg) 
24.{ 
25.printf(“thread2 start\n”); 
26.pthread_cleanup_push(cleanup,”thread 2 first handler”); 
27.pthread_cleanup_push(cleanup,”thread 2 second handler”); 
28.printf(“thread2 push complete\n”); 
29.if (arg) 
30.    pthread_exit((void *)2); 
31.pthread_cleanup_pop(0); 
32.pthread_cleanup_pop(0); 
33.pthread_exit((void*)2); 
34.} 
35.  
36.void err_quit(const char* fmt, …) 
37.{ 
38.printf(“%s\n”,fmt); 
39.exit(1); 
40.} 
41.  
42.int main(void) 
43.{ 
44.int         err; 
45.pthread_t   tid1, tid2; 
46.void        *tret; 
47.  
48.err =pthread_create(&tid1, NULL, thr_fn1, (void *)1); 
49.if (err != 0) 
50.err_quit(“can’t create thread 1: %s\n”, strerror(err)); 
51.  err =pthread_create(&tid2, NULL, thr_fn2, (void *)1); 
52.if (err != 0) 
53.err_quit(“can’t create thread 2: %s\n”, strerror(err)); 
54.err =pthread_join(tid1, &tret); 
55.if (err != 0) 
56.err_quit(“can’t join with thread 1: %s\n”, strerror(err)); 
57.printf(“thread1 exit code %d\n”, (int)tret); 
58.err =pthread_join(tid2, &tret); 
59.if (err != 0) 
60.err_quit(“can’t join with thread 2: %s\n”, strerror(err)); 
61.printf(“thread2 exit code %d\n”, (int)tret); 
62.exit(0); 
63.} 
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
 
void cleanup(void *arg)
{
   printf(“cleanup: %s\n”, (char *)arg);
}
 
void * thr_fn1(void *arg)
{
   printf(“thread 1 start\n”);
   pthread_cleanup_push(cleanup, “thread 1 first handler”);
   pthread_cleanup_push(cleanup, “thread 1 second handler”);
   printf(“thread 1 push complete\n”);
   if (arg)
       return((void *)1);
   pthread_cleanup_pop(0);
   pthread_cleanup_pop(0);
return((void*)1);
}
 
void * thr_fn2(void *arg)
{
printf(“thread2 start\n”);
pthread_cleanup_push(cleanup,”thread 2 first handler”);
pthread_cleanup_push(cleanup,”thread 2 second handler”);
printf(“thread2 push complete\n”);
if (arg)
    pthread_exit((void *)2);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
pthread_exit((void*)2);
}
 
void err_quit(const char* fmt, …)
{
printf(“%s\n”,fmt);
exit(1);
}
 
int main(void)
{
int         err;
pthread_t   tid1, tid2;
void        *tret;
 
err =pthread_create(&tid1, NULL, thr_fn1, (void *)1);
if (err != 0)
err_quit(“can’t create thread 1: %s\n”, strerror(err));
  err =pthread_create(&tid2, NULL, thr_fn2, (void *)1);
if (err != 0)
err_quit(“can’t create thread 2: %s\n”, strerror(err));
err =pthread_join(tid1, &tret);
if (err != 0)
err_quit(“can’t join with thread 1: %s\n”, strerror(err));
printf(“thread1 exit code %d\n”, (int)tret);
err =pthread_join(tid2, &tret);
if (err != 0)
err_quit(“can’t join with thread 2: %s\n”, strerror(err));
printf(“thread2 exit code %d\n”, (int)tret);
exit(0);
}

一般来讲程序展现了什么样选取线程清理管理程序。

2.响应撤消央浼时

pthread_tpthread_self(void);

pthread_exit函数:

#include<pthread.h>

thread 1 exit code 1

pthread_exit和pthread_create函数的无类型指针参数恐怕传递一个繁杂的构造的地方,单数该组织所选取的内部存款和储蓄器调用者完结调用以往必需如故是卓有成效的。能够选择全局结构依旧malloc函数分配栈结构。

new thread:  pid 2846 tid 3079359344 (0xb78b4b70)

一个历程中的全体线程都能够访谈该进程的组成都部队件(如文件呈报符和内部存款和储蓄器)。

#include<pthread.h>

cleanup: thread 2 second handler

intpthread_create(pthread_t *thread, const pthread_attr_t *attr,

retval
是四个无类型的指针,与传给运维例程的单个参数近似。进度中的别的线程能够透过调用pthread_join函数访谈到那个指针。

void printids(const char *s)
{
    pid_t       pid;
    pthread_t   tid;

 #include<pthread.h>

新创建的线程从start_routine函数地址开首运营,该函数唯有叁个无类型指针参数arg,若是急需向start_routine函数传递的参数不唯有三个,那么要求把那几个参数放到三个组织中,然后把那些结构的地址作为arg参数字传送入。

再次回到值:若成功则重返0,否则重回错误编号。

推行及出口结果如下:

         #include<pthread.h>

实践及出口:

int main(void)
{
    int     err;

1.调用pthread_exit时

在线程中,线程ID的档案的次序是pthread_t类型,由于在Linux下线程选拔POSIX标准,所以,在分化的体系下,pthread_t的品种是见仁见智的,譬喻在ubuntn下,是unsigned
long类型,而在solaris系统中,是unsigned
int类型。而在FreeBSD上才用的是组织题指针。
所以不能够平昔运用==判读,而应当使用pthread_equal来判断。

main thread: pid2846 tid 3079362240 (0xb78b56c0)

void * thr_fn(void *arg)
{
    printids(“new thread: “);
return((void *)0);
}

thread 2 exiting

void err_quit(const char* fmt, …)
{
printf(“%s\n”,fmt);
exit(1);
}

cleanup: thread 2 first handler

[cpp] view plaincopyprint?01.#include <stdio.h>  
02.#include <stdlib.h>  
03.#include <pthread.h>  
04. 
05.pthread_t ntid; 
06. 
07.void printids(const char *s) 
08.{ 
09.    pid_t       pid; 
10.    pthread_t   tid; 
11. 
12.    pid = getpid(); 
13.    tid = pthread_self(); 
14.    printf(“%s pid %u tid %u (0x%x)\n”, s, (unsigned int)pid, 
15.      (unsigned int)tid, (unsigned int)tid); 
16.} 
17. 
18.void * thr_fn(void *arg) 
19.{ 
20.    printids(“new thread: “); 
21.return((void *)0); 
22.} 
23. 
24.void err_quit(const char* fmt, …) 
25.{ 
26.printf(“%s\n”,fmt); 
27.exit(1); 
28.} 
29. 
30. 
31.int main(void) 
32.{ 
33.    int     err; 
34. 
35.    err = pthread_create(&ntid, NULL, thr_fn, NULL); 
36.    if (err != 0) 
37.        err_quit(“can’t create thread: %s\n”, strerror(err)); 
38.printids(“main thread:”); 
39.    sleep(1); 
40.    exit(0); 
41.} 
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图