linux如何实现多线程,linux多线程编程实例

linux如何实现多线程,linux多线程编程实例,Linux多线程编程快速入门

本文主要介绍Linux多线程编程的快速入门,其中涉及到线程的基础知识、线程识别、线程创建、线程终止、线程终止等相关内容。边肖认为这很好。我就分享到这里,有需要的朋友可以参考一下。

目录

5.1线程连接5.2线程分离本文主要对Linux下的多线程进行介绍。虽然是介绍,但是很详细。希望你能通过这篇文章对Linux多线程编程的概念有一定的了解。如下。

1 线程基本知识

进程是资源管理的基本单位,而线程是系统调度的基本单位。线程是操作系统可以执行调度操作的最小单位。它包含在流程中,是流程中的实际操作单元。线程是指流程中控制流的单个序列。多个线程可以在一个进程中并发,每个线程并行执行不同的任务。

一个进程在某一时刻只能做一件事。有了多个控制线程,程序被设计成在某个时间做多件事,每个线程处理自己的任务。

需要注意的是,即使程序运行在单核处理器上,也能获得多线程编程模式的好处。处理器数量不影响程序结构,所以不管处理器数量多少,程序都可以通过线程来简化。

Linux操作系统使用POSIX线程作为系统标准线程,为操作线程定义了一套API。

2. 线程标识

就像一个进程有一个ID一样,每个线程都有一个线程ID。不同的是,进程ID在整个系统中是唯一的,而线程是依附于进程的,它的线程ID只有在它所属的进程中才有意义。线程ID由pthread _ t表示。

//pthread_self直接返回调用线程的ID

包含pthread.h

pthread _ t pthread _ self(void);

判断两个线程id的大小没有任何意义,但有时可能需要判断两个给定的线程id是否相等。使用以下界面:

//pthread_equal如果t1和t2指定的线程ID相同,返回0;否则,将返回一个非零值。

包含pthread.h

int pthread_equal(pthread_t t1,pthread _ t T2);

3. 线程创建

线程的生命周期从它被创建的那一刻开始。创建线程的接口:

#include pthread.h

int pthread _ create(pthread _ t * thread,const pthread_attr_t *attr,

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

功能参数:

Thread (output参数),线程创建成功后pthread_create返回的线程句柄,用于在后续操作线程的API中标记新创建的线程;

Start_routine(输入参数),创建新线程的入口函数;

Arg(输入参数),传递给新线程入口函数的参数;

Attr(输入参数),指定新创建线程的属性,如线程栈大小等。如果值为NULL,则使用系统默认属性。

函数返回值:

成功,返回0;

失败,返回相关错误代码。

注意:

1.主线程,它是一个进程的初始线程,它的入口函数就是主函数。

2.新线程的运行时间。一个线程在被创建后可能不会立即被执行,甚至在创建它的线程结束后还没有被执行;也有可能在当前线程从pthread_create返回之前,新线程已经在运行了,甚至在pthread_create之前,新线程在从当前线程返回之前就已经完成了。

程序示例:

#包含stdio.h

#包含stdlib.h

#include pthread.h

#包括unistd.h

void print id(const char * s){

pid _ t pid

pthread _ t tid

PID=getpid();

tid=pthread _ self();

printf(%s,pid %lu tid %lu (0x%lx)n ,s,(无符号长整型)pid,(无符号长整型)tid,

(无符号长整型)tid);

}

void *thread_func(void *arg){

print ids( new thread:);

return((void *)0);

}

int main() {

int err

pthread _ t tid

err=pthread_create(tid,NULL,thread_func,NULL);

如果(呃!=0) {

fprintf(stderr,创建线程失败。 n’);

退出(-1);

}

printids(“主线程:”);

睡眠(1);

返回0;

}

注意,在上面的程序中,主线程休眠了一秒钟。如果没有,主线程将不会休眠,它可能会退出,这样新线程可能不会运行。我自己注释掉了sleep函数,在新线程可以输出之前发现了很多次。

编译命令:

gcc -o螺纹thread . c-LP螺纹

运行结果如下:

主线程:PID 889 tid 139846854309696(0x7f 30 a 212 f 740)

新线程:PID 889 tid 139846845961984(0x7f 30 a 1939700)

您可以看到两个线程的进程id是相同的。在其流程中共享资源。

4. 线程终止

线程终止有两种形式:被动终止和主动终止。

被动终止有两种方式:

1.当线程所在的进程终止时,任何执行exit、_Exit或_exit函数的线程都会导致该进程终止,从而导致所有附属于该进程的线程终止。

2.其他线程调用pthread_cancel请求取消该线程。

主动终止也有两种方式:

1.在线程的入口函数中执行return语句,主函数(主线程入口函数)执行return语句会导致进程终止,从而导致所有附着在进程上的线程终止。

2.线程调用pthread_exit函数,主函数(主线程入口函数)调用pthread_exit函数。主线程终止,但如果进程中有其他线程,进程将继续存在,进程中的其他线程将继续运行。

线程终止功能:

包含pthread.h

void pthread _ exit(void * retval);

调用线程的pthread_exit函数会导致调用线程终止并返回retval指定的内容。

注意:retval不能指向这个线程的堆栈空间,否则可能会变成一个野指针!

5. 管理线程的终止

5.1 线程的连接

一个线程的终止是另一个线程的异步事件。有时,我们希望在执行某些操作之前,等待ID为的线程终止。pthread_join函数为我们提供了这个函数,叫做线程连接:

包含pthread.h

int pthread _ join(pthread _ t thread,void * * retval);

参数描述:

Thread(输入参数),指定我们要等待的线程。

Retval(输出参数),我们等待线程终止时的返回值,是线程入口函数或者调用pthread_exit函数的参数中的返回值。

返回值:

如果成功,则返回0。

错误,返回一个肯定的错误代码。

当线程X与线程Y连接时,如果线程Y还在运行,线程X会阻塞,直到线程Y终止;如果线程Y在被连接之前已经被终止,那么线程X的连接调用将立即返回。

连接线程实际上还有另一层含义。一个线程终止后,如果没有人连接,终止线程占用的资源不会被系统回收,终止线程就会变成僵尸线程。因此,当我们连接到一个线程时,我们实际上是在告诉系统,被终止线程的资源是可以回收的。

注意:再次连接一个已经连接的线程会导致不可预知的行为!

5.2 线程的分离

有时候我们并不关心一个线程是否已经被终止,我们只是希望如果一个线程被终止,系统能够自动回收被终止线程占用的资源。pthread_detach函数为我们提供了这个函数,叫做线程分离:

#include pthread.h

int pthread _ detach(pthread _ t thread);

默认情况下,线程被终止,在系统可以恢复其资源之前,需要连接它。如果我们调用pthread_detach函数来分离一个线程,系统会在线程终止后自动回收它的资源。

/*

*文件名:thread_sample1.c

*描述:演示线程的基本操作

*/

#包含stdio.h

#包含stdlib.h

#包括unistd.h

#include pthread.h

/*子线程1的入口函数*/

void *thread_routine1

{

fprintf(stdout, thread1: hello world! n’);

睡眠(1);

/*子线程1在此退出*/

返回NULL

}

/*子线程2入口函数*/

void *thread_routine2

{

fprintf(stdout, thread2:我正在运行. n’);

pthread _ t main _ thread=(pthread _ t)arg;

/*把自己分开,就再也联系不上了*/

pthread _ detach(pthread _ self());

/*确定主线程ID是否等于子线程2ID */

如果(!pthread_equal(main_thread,pthread _ self()){

fprintf(标准输出,线程2:主线程身份证明(identification)不等于线程2 n’);

}

/*等待主线程终止*/

pthread_join(main_thread,NULL);

fprintf(标准输出,线程2:主线程退出! n’);

fprintf(stdout, thread2: exit! n’);

fprintf(标准输出,线程2:进程退出! n’);

/*子线程2在此终止,进程退出*/

pthread_exit(空);

}

int main(int argc,char *argv[])

{

/*创建子线程1*/

pthread _ t t1

if (pthread_create(t1,NULL,thread_routine1,NULL)!=0) {

fprintf(stderr,创建线程失败. n );

退出(-1);

}

/*等待子线程一终止*/

pthread_join(t1,NULL);

fprintf(标准输出,主线程:线程1终止! n n’);

/*创建子线程2,并将主线程身份证明传递给子线程2*/

pthread _ t t2

if (pthread_create(t2,NULL,thread_routine2,(void *)pthread_self())!=0) {

fprintf(stderr,创建线程失败. n );

退出(-1);

}

fprintf(标准输出,主线程:休眠. n’);

睡眠(3);

/*主线程使用pthread_exit函数终止,进程继续存在*/

fprintf(标准输出,主线程:退出! n’);

pthread_exit(空);

fprintf(标准输出,主线程:永远不要到达这里! n’);

返回0;

}

最终的执行结果如下:

线程1:你好,世界!

主线程:线程1终止!

主线:睡觉.

线程2:我正在运行.

线程2:主线程身份证明(identification)不等于线程2

主线程:退出!

线程2:主线程退出!

线程2:退出!

线程2:进程退出!

总结

以上就是本文关于Linux操作系统操作系统多线程编程快速入门的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

linux如何实现多线程,linux多线程编程实例