深入探究-linux中的pthread多线程技术-linux里 (深入探究立春)

教程大全 2025-07-16 08:20:34 浏览

随着计算机科学技术的不断发展,多线程技术逐渐成为程序设计中不可或缺的一部分。而Linux作为一种开源的操作系统,其中的pthread多线程技术更是被广泛应用于大大小小的项目中。本文将深入探究Linux中的pthread多线程技术,并从以下三个方面详细介绍:线程的创建与销毁、线程同步、线程通信。

一、线程的创建与销毁

在Linux中,创建线程的方法十分简单,只需要使用pthread_create()函数即可。

pthread_create()函数的声明如下:

`int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);`

这个函数有四个参数,分别如下:

– **thread**:是指向pthread_t类型的指针,用来存储新线程的ID。

– **attr**:是指向pthread_attr_t类型的指针,它用来设置新线程的属性。

– **start_routine**:是一个指向函数的指针,它代表新线程所要执行的函数。

– **arg**:是一个指针,在新线程启动后作为参数传递给start_routine函数。

一个简单的创建线程的示例代码如下:

void *myThread(void *arg)

printf(“This is myThread!\n”);

pthread_exit(NULL);

pthread_t tid;

pthread_create(&tid, NULL, myThread, NULL);

printf(“This is mn thread!\n”);

pthread_exit(NULL);

在上面的代码中,我们创建了一个名为myThread的函数,它被用作新线程执行函数的入口点。然后在主函数中,我们使用pthread_create()函数创建了一个名为tid的线程,并将myThread函数作为新线程的入口点。最后我们用pthread_exit()函数来结束程序,并等待所有线程退出。

线程的销毁也非常简单,只需要使用pthread_exit()函数即可。这个函数的作用是结束当前线程,并将返回值传递给父线程。

二、线程同步

线程同步是一个十分重要的概念,它指的是确保多个线程在某一时刻执行的顺序是被正确安排的。在Linux中,有许多技术可以用于线程同步,比如互斥锁、信号量、条件变量等等。

1、互斥锁

互斥锁是线程同步中最常用的技术之一。它可以确保一段关键代码在任意时刻只能有一个线程在执行,从而确保了代码的正确性。

在Linux中,互斥锁使用pthread_mutex_t结构体来表示。pthread_mutex_lock()函数可以锁住互斥锁,而pthread_mutex_unlock()函数则可以释放它。

一个简单的互斥锁示例代码如下:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int count = 0;

void *myThread(void *arg)

for(int i=0; i

pthread_mutex_lock(&mutex);

pthread_mutex_unlock(&mutex);

pthread_exit(NULL);

pthread_t tid1, tid2;

pthread_create(&tid1, NULL, myThread, NULL);

pthread_create(&tid2, NULL, myThread, NULL);

pthread_join(tid1, NULL);

pthread_join(tid2, NULL);

printf(“count = %d\n”, count);

pthread_exit(NULL);

在上面的代码中,我们定义了一个名为mutex的互斥锁,并将它初始化为PTHREAD_MUTEX_INITIALIZER。在myThread函数中,我们使用互斥锁来确保count变量的安全访问。我们使用pthread_join()函数来等待两个线程退出,并打印出count的值。

2、信号量

信号量是另一种用于线程同步的技术。它可以用来控制对共享资源的访问,从而确保线程之间的正确协调。

在Linux中,信号量使用sem_t结构体来表示。sem_wt()函数可以锁住信号量,sem_post()函数则可以释放它。

一个简单的信号量示例代码如下:

int count = 0;

void *myThread(void *arg)

for(int i=0; i

sem_wt(&sem);

sem_post(&sem);

pthread_exit(NULL);

sem_init(&sem, 0, 1);

pthread_t tid1, tid2;

pthread_create(&tid1, NULL, myThread, NULL);

pthread_create(&tid2, NULL, myThread, NULL);

pthread_join(tid1, NULL);

pthread_join(tid2, NULL);

printf(“count = %d\n”, count);

pthread_exit(NULL);

在上面的代码中,我们使用sem_init()函数初始化了一个名为sem的信号量。在myThread函数中,我们使用信号量来确保count变量的安全访问。我们使用pthread_join()函数来等待两个线程退出,并打印出count的值。

3、条件变量

条件变量是另一种用于线程同步的技术。它可以让线程在特定的条件下等待或被唤醒,从而达到线程之间相互通信的目的。

在Linux中,条件变量使用pthread_cond_t结构体来表示。pthread_cond_wt()函数可以让线程在条件变量上等待,pthread_cond_signal()函数则可以唤醒它。

一个简单的条件变量示例代码如下:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int flag = 0;

void *thread1(void *arg)

pthread_mutex_lock(&mutex);

pthread_cond_signal(&cond);

pthread_mutex_unlock(&mutex);

pthread_exit(NULL);

void *thread2(void *arg)

pthread_mutex_lock(&mutex);

while(flag == 0)

pthread_cond_wt(&cond, &mutex);

printf(“Thread2\n”);

pthread_mutex_unlock(&mutex);

pthread_exit(NULL);

pthread_t tid1, tid2;

pthread_create(&tid1, NULL, thread1, NULL);

pthread_create(&tid2, NULL, thread2, NULL);

pthread_join(tid1, NULL);

pthread_join(tid2, NULL);

pthread_exit(NULL);

在上面的代码中,我们创建了两个线程,分别执行thread1和thread2函数。在thread1函数中,我们将flag变量设置为1,并通过调用pthread_cond_signal()函数唤醒在条件变量上等待的线程。在thread2函数中,我们循环等待flag变量被设置为1,并打印出”Thread2″。

三、线程通信

线程通信是指通过某种机制,使得一个线程可以向另一个线程传递数据或信息。在Linux中,常常使用共享内存、消息队列等技术来实现线程通信。

1、共享内存

共享内存是一种允许多个线程共享内存区域的技术。在Linux中,可以使用shm_open()函数和mmap()函数来创建和映射共享内存区域。

一个简单的共享内存示例代码如下:

const char *name = “/shmtest”;

const int SIZE = 4096;

int shm_fd;

shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);

ftruncate(shm_fd, SIZE);

ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);

sprintf((char *)ptr, “Hello, world!”);

printf(“%s\n”, (char *)ptr);

munmap(ptr, SIZE);

shm_unlink(name);

在上面的代码中,我们创建了一个名为”/shmtest”的共享内存区域,并将它映射到了内存空间中。然后我们向共享内存区域写入了一些数据,并打印出来。最后我们释放了共享内存,并删除了它。

2、消息队列

消息队列是另一种用于线程通信的技术。它可以让一个线程向另一个线程发送消息,从而实现线程之间的数据交换。

在Linux中,可以使用msgget()函数、msgsnd()函数和msgrcv()函数来创建和使用消息队列。

一个简单的消息队列示例代码如下:

struct msgbuf

long mtype;

char mtext[128];

struct msgbuf buf;

key = ftok(“/tmp/msg.temp”, 1);

msgid = msgget(key, 0666 | IPC_CREAT);

buf.mtype = 1;

strncpy(buf.mtext, “Hello, world!”, sizeof(buf.mtext));

msgsnd(msgid, &buf, sizeof(buf.mtext), 0);

msgrcv(msgid, &buf, sizeof(buf.mtext), 1, 0);

printf(“%s\n”, buf.mtext);

msgctl(msgid, IPC_RMID, NULL);

在上面的代码中,我们创建了一个名为”/tmp/msg.temp”的key,并使用ftok()函数将它转换成key_t类型。然后我们使用msgget()函数创建了一个消息队列,将一条消息发送到队列中,并从队列中接收一条消息并打印出来。最后我们通过msgctl()函数删除了这个消息队列。

相关问题拓展阅读:

LINUX 的pthread_sigmask含义

是的。

pthread_sigmask(SIG_BLOCK, &newmask, &oldmask)这句话代表线程理睬newmask和oldmask信号集面信号。

一个进程的信号屏蔽字规定了当前阻塞而不能搭指如递送给该进程的信号知启集。

当前的信号屏蔽字会由oldmask指针返回。

参数:SIG_BLOCK 表示 该进程新的信号屏蔽字是其当前逗拍信号屏蔽字和set指向信号集的并集。newmask中包含了我们希望阻塞的附加信号。

linux下线程pthread编译时为什么要加lpthread

shibixiao | 六级

lpthread是表示要连接到pthread的库是这让脊里省略的lib,你应该可以找到共享库libpthread.so的兆滑蔽

因为pthread编程用到的函数在pthread库里族州面,就像你使用pow等数学计算函数,需要用到math.h

需要 -lm

lpthread是表模颤示要连接到pthread的库是这里省略信搭的lib,你应该可以找到共享旦坦败库libpthread.so的

加共享库

关于linux里-pthread的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

香港服务器首选树叶云,2H2G首月10元开通。树叶云(shuyeidc.com)提供简单好用,价格厚道的香港/美国云 服务器 和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。


深入探究立春

linux下怎么在等待线程结束中设置超时

多线程退出有三种方式:(1)执行完成后隐式退出;(2)由线程本身显示调用pthread_exit函数退出;pthread_exit(void*retval);(3)被其他线程用pthread_cance函数终止:pthread_cance(pthread_tthread);用event来实现。 在子线程中,在循环内检测event。 while(!_Active()){}当退出循环体的时候,自然return返回。 这样子线程会优雅的结束。 注意:选用非等待的检测函数。 pthread线程有两种状态,joinable(非分离)状态和detachable(分离)状态,默认为joinable。 joinable:当线程函数自己返回退出或pthread_exit时都不会释放线程所用资源,包括栈,线程描述符等(有人说有8k多,未经验证)。 detachable:线程结束时会自动释放资源。 Linuxmanpagesaid:Whenajoinablethreadterminates,itsmemoryresources(threaddescriptorandstack)arenotdeallocateduntilanotherthreadperformspthread_,pthread_joinmustbecalledonceforeachjoinablethreadcreatedtoavoidmemoryleaks.因此,joinable线程执行完后不使用pthread_join的话就会造成内存泄漏。 解决法:1.//创建线程前设置PTHREAD_CREATE_DETACHED属性pthread_attr_tattr;pthread_tthread;pthread_attr_init(&attr);pthread_attr_setdetachstat(&attr,PTHREAD_CREATE_DETACHED);pthread_create(&thread,&attr,&thread_function,NULL);pthread_attr_destroy(&attr);2.当线程为joinable时,使用pthread_join来获取线程返回值,并释放资源。 3.当线程为joinable时,也可在线程中调用pthread_detach(pthread_self());来分离自己。

怎么样才算得上熟悉多线程编程

1. 了解进程线程的基本概念,能用一种语言在一个平台上实现一个多线程的例子。 (这些不会还写熟悉多线程就太大无畏了)2. 了解为什么要用Mutex之类的工具做锁来同步和保护资源。 弄懂诸如racing condition,死锁之类的概念。 50%公司的见面题,用来砍死大无畏。 3. 了解编译器优化带来的影响,了解cache的影响,了解volatile,memory barrier之类的概念。 如果是主Java的话,去了解一下JVM的内存模型。 以上这些偏硬偏系统端的公司喜欢问,不过由于太基础,稍稍好奇一点的多线程领域程序员都应该会了解,否则略显大无畏。 4. 了解一下你主攻平台+语言所提供的工具库,知道常用的工具的用法和使用场景:Mutex,Semaphore,原子操作集,Condition Variable,spin lock。 这几个算是比较常用的,在各个平台+语言也都有对应实现。 老实说,spinlock,condition variable是我工作里从没用过的,但是也被问过,其他几个都太常用了,如果是java的话再多看一组Executor相关的,以及Java多线程相关的keywords,和object本身提供的同步函数,wait notify之类的,在主Java的公司问过。 5. 了解常用的多线程设计范式,比如读写锁(Reader/Writer Lock,非常经典的范式,有偏向读和写的不同变形,至少被要求写过3次),生产消费范式(写过2次),一些常用容器的实现,比如BlockingQueue(写过3次)或者concurrentHashmap(写过2次)。 如果是主Java的话可以看看JDK的实现。 熟悉一下一些算不上多线程设计模式的小技巧,比如传递只读对象可以避免加锁,或者Copy传递以防外部修改之类的(讨论环节被问过)。 另外值得特别一提的一个小细节是,Singleton的线程安全是个很有意思而且容易出错的话题,值得一看(只被问过一次,不过我答挂了,所以印象及其深)。 还有可能会问的是一些有趣的小场景让你实现一些功能需要线程安全,无法特别准备,但是你能了解上面说的这些范式,不傻的话大多数都能想出来。

Linux下调用pthread库创建的线程是属于用户级线程还是内核级线程

pthread运行于用户态,内核态有kthread。

本文版权声明本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请联系本站客服,一经查实,本站将立刻删除。

发表评论

热门推荐