c 多线程 linux?linux多线程pthread

大家好,今天小编来为大家解答c 多线程 linux这个问题,linux多线程pthread很多人还不知道,现在让我们一起来看看吧!

linux下 c中怎么让才能安全关闭线程

多线程程序中,特别是频繁申请,释放线程的情况下,就要注意线程的关闭,最好使用线程池。

一,线程退出方式

(1)执行完成后隐式退出;

(2)由线程本身显示调用pthread_exit函数退出;

pthread_exit(void* retval);

(3)被其他线程用pthread_cance函数终止:

pthread_cance(pthread_t thread);

二,线程状态

pthread线程有两种状态,joinable(非分离)状态和detachable(分离)状态,默认为joinable。

joinable:当线程函数自己返回退出或pthread_exit时都不会释放线程所用资源,包括栈,线程描述符等(有人说有8k多,未经验证)。

detachable:线程结束时会自动释放资源。

joinable线程执行完后不使用pthread_join的话就会造成内存泄漏。

解决办法:

1、创建线程前设置 PTHREAD_CREATE_DETACHED属性

pthread_attr_t attr;

pthread_t thread;

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());来分离自己。

linux C下多线程接收数据怎么进行存储再统一处理

在Linux系统中使用C/C++进行多线程编程时,我们遇到最多的就是对同一变量的多线程读写问题,大多情况下遇到这类问题都是通过锁机制来处理,但这对程序的性能带来了很大的影响,当然对于那些系统原生支持原子操作的数据类型来说,我们可以使用原子操作来处理,这能对程序的性能会得到一定的提高。那么对于那些系统不支持原子操作的自定义数据类型,在不使用锁的情况下如何做到线程安全呢?本文将从线程局部存储方面,简单讲解处理这一类线程安全问题的方法。

一、数据类型

在C/C++程序中常存在全局变量、函数内定义的静态变量以及局部变量,对于局部变量来说,其不存在线程安全问题,因此不在本文讨论的范围之内。全局变量和函数内定义的静态变量,是同一进程中各个线程都可以访问的共享变量,因此它们存在多线程读写问题。在一个线程中修改了变量中的内容,其他线程都能感知并且能读取已更改过的内容,这对数据交换来说是非常快捷的,但是由于多线程的存在,对于同一个变量可能存在两个或两个以上的线程同时修改变量所在的内存内容,同时又存在多个线程在变量在修改的时去读取该内存值,如果没有使用相应的同步机制来保护该内存的话,那么所读取到的数据将是不可预知的,甚至可能导致程序崩溃。

如果需要在一个线程内部的各个函数调用都能访问、但其它线程不能访问的变量,这就需要新的机制来实现,我们称之为Static memory local to a thread(线程局部静态变量),同时也可称之为线程特有数据(TSD: Thread-Specific Data)或者线程局部存储(TLS: Thread-Local Storage)。这一类型的数据,在程序中每个线程都会分别维护一份变量的副本(copy),并且长期存在于该线程中,对此类变量的操作不影响其他线程。如下图:

二、一次性初始化

在讲解线程特有数据之前,先让我们来了解一下一次性初始化。多线程程序有时有这样的需求:不管创建多少个线程,有些数据的初始化只能发生一次。列如:在C++程序中某个类在整个进程的生命周期内只能存在一个实例对象,在多线程的情况下,为了能让该对象能够安全的初始化,一次性初始化机制就显得尤为重要了。——在设计模式中这种实现常常被称之为单例模式(Singleton)。Linux中提供了如下函数来实现一次性初始化:

#include<pthread.h>

// Returns 0 on success, or a positive error number on error

int pthread_once(pthread_once_t*once_control, void(*init)(void));

利用参数once_control的状态,函数pthread_once()可以确保无论有多少个线程调用多少次该函数,也只会执行一次由init所指向的由调用者定义的函数。init所指向的函数没有任何参数,形式如下:

void init(void)

{

// some variables initializtion in here

}

另外,参数once_control必须是pthread_once_t类型变量的指针,指向初始化为PTHRAD_ONCE_INIT的静态变量。在C++0x以后提供了类似功能的函数std::call_once(),用法与该函数类似。使用实例请参考实现。

Linux 多线程详解 —— 什么是线程

在Linux中,虽然内核层面并不直接支持线程,而是通过轻量级进程(LWP)来实现。实际上,我们通常所说的线程是C库中的概念,它是一个工作线程,会复制主线程的task_struct,并共享主线程的mm_struct。线程ID由task_struct中的pid表示,而tgid则是线程组ID,主线程的pid和tgid相同,工作线程的pid和tgid则不同。

要查看线程ID,可以使用`ps-eLf`命令。例如,进程polkitd(进程ID 731)就包含6个线程,每个线程有自己的ID,如731, 764, 765等。为了避免线程调用栈混乱,因为工作线程共享mm_struct,所以它们通常在共享区(默认8M大小)压栈,而非独立的堆栈。

多线程的优势在于它能提高并发处理能力,比如银行办理业务的例子中,多个窗口代表多个工作线程,能同时处理多个客户请求。然而,线程间共享资源可能会导致同步和数据一致性问题,且线程创建和切换也会增加一定的开销。

线程的对等关系在编程中很重要,需要注意的是,虽然线程提供了并行处理的能力,但也需要合理设计以避免线程间的混乱。如果你对Linux、C/C++技术感兴趣,可以加入学习群【960994558】,获取更多相关资源和讨论。

阅读剩余
THE END