当前位置: 首页 > news >正文

上海松江做网站公司百度电商推广

上海松江做网站公司,百度电商推广,新闻网站开发书籍,贵州安顺做公司网站1 线程和进程的区别 资源分配和调度: 进程(火车)是操作系统进行资源分配和调度的最小单位。它有自己的独立资源空间,包括内存、文件句柄等。线程(车厢)是CPU调度的最小单位。一个进程可以包含多个线程&…

1 线程和进程的区别

  1. 资源分配和调度:

    • 进程(火车)是操作系统进行资源分配和调度的最小单位。它有自己的独立资源空间,包括内存、文件句柄等。
    • 线程(车厢)是CPU调度的最小单位。一个进程可以包含多个线程,它们共享相同的资源空间,如内存,但有各自的执行路径。
  2. 数据共享:

    • 进程间的数据共享相对困难,需要使用进程间通信(IPC)的机制。
    • 同一进程内的不同线程可以直接共享数据,因为它们共享相同的内存空间。
  3. 稳定性和影响范围:

    • 进程间是相互独立的,一个进程的崩溃通常不会影响其他进程。
    • 同一进程下的线程是共享相同的进程资源,一个线程的崩溃可能导致整个进程崩溃。
  4. 资源消耗和扩展性:

    • 进程比线程消耗更多的计算机资源,因为它们有独立的资源空间。
    • 进程可以在多台机器上运行,而线程适合在多核处理器上运行。
  5. 内存地址管理:

    • 进程的内存地址可以上锁,实现互斥访问,确保线程安全。
    • 进程的内存地址可以限定使用量,通过信号量等机制控制资源的访问。

这个比喻涵盖了进程和线程的许多关键概念,希望能够更好地帮助理解它们之间的区别和关系。

2 基础线程创建

2.1 代码示例

以下最简单的事例来理解线程:

//test.cpp
#include <iostream>
#include <pthread.h>  //必须的头文件using namespace std;#define NUM_THREADS 5// 线程的运行函数
void* say_hello(void* args)
{cout << "Hello Runoob!" << endl;return 0;
}int main()
{// 定义线程的 id 变量,多个变量使用数组pthread_t tids[NUM_THREADS];for(int i = 0; i < NUM_THREADS; ++i){//参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数int ret = pthread_create(&tids[i], NULL, say_hello, NULL);if (ret != 0){cout << "pthread_create error: error_code=" << ret << endl;}}//等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过来;//**当linux中,主线程以pthread_exit(NULL)作为返回值,则主线程会等待子线程。**pthread_exit(NULL);}

2.2 线程代码编译

2.2.1 命令行编译

使用 -lpthread 库编译下面的程序:

$ g++ test.cpp -lpthread -o test.o

2.2.2 Makefile编译

但是如果用Makefile一堆文件编译的情况下如何设置

# Makefile中变量定义如:标签=内容,后面的变量引用需要$(标签)
GPU=0
CUDNN=0
OPENCV=0
OPENMP=0 # OpenMP是一套支持跨平台共享内存方式的多线程并发的编程API
DEBUG=0ARCH= -gencode arch=compute_30,code=sm_30 \-gencode arch=compute_35,code=sm_35 \-gencode arch=compute_50,code=[sm_50,compute_50] \-gencode arch=compute_52,code=[sm_52,compute_52]
#      -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated?# This is what I use, uncomment if you know your arch and want to specify
# ARCH= -gencode arch=compute_52,code=compute_52VPATH=./src/:./examples
SLIB=libdarknet.so #待生成的动态链接库
ALIB=libdarknet.a  #待生成的静态链接库
EXEC=darknet #待生成的执行文件名称
OBJDIR=./obj/ #生成目标文件的目录,即当期目录下obj子目录CC=gcc
CPP=g++
NVCC=nvcc #nvidia编译器
AR=ar 	#ar,Linux系统的一个备份压缩命令,用于创建、修改备存文件(archive)。这里的ar命令是将目标文件打包为静态链接库。
ARFLAGS=rcs #ar命令的参数 -rcs。-r:将文件插入备存文件中 c:建立备存文件 s:若备存文件中包含了对象模式,可利用此参数建立备存文件的符号表
OPTS=-Ofast
#编译选项中指定 -pthread 会附加一个宏定义 -D_REENTRANT,该宏会导致 libc 头文件选择那些thread-safe的实现;
#链接选项中指定 -pthread 则同 -lpthread 一样,只表示链接 POSIX thread 库。由于 libc 用于适应 thread-safe 的宏定义可能变化,
#因此在编译和链接时都使用 -pthread 选项而不是传统的 -lpthread 能够保持向后兼容,并提高命令行的一致性。
LDFLAGS= -lm -pthread 
COMMON= -Iinclude/ -Isrc/
#-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
#unknow-pragmas:使用未知的#pragma指令
CFLAGS=-Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC ifeq ($(OPENMP), 1) #条件判断
CFLAGS+= -fopenmp
endififeq ($(DEBUG), 1) 
OPTS=-O0 -g #-g选项可以产生带有调试信息的目标代码
endifCFLAGS+=$(OPTS)ifeq ($(OPENCV), 1) 
COMMON+= -DOPENCV #相当于C语言中的#define OPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv` -lstdc++  #pkg-config能够把头文件和库文件的位置指出来,给编译器使用
COMMON+= `pkg-config --cflags opencv` 
endififeq ($(GPU), 1) 
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endififeq ($(CUDNN), 1) 
COMMON+= -DCUDNN 
CFLAGS+= -DCUDNN
LDFLAGS+= -lcudnn
endif#OBJ表示需要生成的目标文件
OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o upsample_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o logistic_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o  lstm_layer.o l2norm_layer.o yolo_layer.o iseg_layer.o image_opencv.o
EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o instance-segmenter.o darknet.o
ifeq ($(GPU), 1) 
LDFLAGS+= -lstdc++ 
OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o avgpool_layer_kernels.o
endifEXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA)) #addprefix统一添加前缀
OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet.h #wildcard展开src文件下所有后缀为.h的头文件;all: obj backup results $(SLIB) $(ALIB) $(EXEC) #主要任务all和其所有依赖
#all: obj  results $(SLIB) $(ALIB) $(EXEC)$(EXEC): $(EXECOBJ) $(ALIB)$(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(ALIB) #$@自动变量,表示目标名称,这里指$(EXEC),实际为darknet;$^指代所有前置条件,之间以空格分隔$(ALIB): $(OBJS)$(AR) $(ARFLAGS) $@ $^ $(SLIB): $(OBJS)$(CC) $(CFLAGS) -shared $^ -o $@ $(LDFLAGS) #-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件$(OBJDIR)%.o: %.cpp $(DEPS)$(CPP) $(COMMON) $(CFLAGS) -c $< -o $@ #$<指代第一个前置条件,这里指%.cpp; -c编译、汇编到目标代码,不进行链接$(OBJDIR)%.o: %.c $(DEPS)$(CC) $(COMMON) $(CFLAGS) -c $< -o $@$(OBJDIR)%.o: %.cu $(DEPS)$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@obj:mkdir -p obj #-p 确保目录名称存在,不存在的就建一个
backup:mkdir -p backup
results:mkdir -p results.PHONY: cleanclean:rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ) $(OBJDIR)/*

3 线程属性

1、pthread_attr_init
功能: 对线程属性变量的初始化。2、pthread_attr_setscope
功能: 设置线程 __scope 属性。scope属性表示线程间竞争CPU的范围,也就是说线程优先级的有效范围。POSIX的标准中定义了两个值:PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同进程中的线程竞争CPU。默认为PTHREAD_SCOPE_PROCESS。目前LinuxThreads仅实现了PTHREAD_SCOPE_SYSTEM一值。3、pthread_attr_setdetachstate
功能: 设置线程detachstate属性。该表示新线程是否与进程中其他线程脱离同步,如果设置为PTHREAD_CREATE_DETACHED则新线程不能用pthread_join()来同步,且在退出时自行释放所占用的资源。缺省为PTHREAD_CREATE_JOINABLE状态。这个属性也可以在线程创建并运行以后用pthread_detach()来设置,而一旦设置为PTHREAD_CREATE_DETACH状态(不论是创建时设置还是运行时设置)则不能再恢复到PTHREAD_CREATE_JOINABLE状态。4、pthread_attr_setschedparam
功能: 设置线程schedparam属性,即调用的优先级。5、pthread_attr_getschedparam
功能: 得到线程优先级。
#include <stdlib.h>   
#include <stdio.h>   
#include <errno.h>   
#include <pthread.h>   
static void pthread_func_1 (void);   
static void pthread_func_2 (void);   int main (int argc, char** argv)   
{   pthread_t pt_1 = 0;   pthread_t pt_2 = 0;   pthread_attr_t atrr = {0};   int ret = 0;   //初始化属性线程属性pthread_attr_init (&attr);   pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);   pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);   ret = pthread_create (&pt_1, &attr, pthread_func_1, NULL);   if (ret != 0)   {   perror ("pthread_1_create");   }  
**//线程一的线程函数一结束就自动释放资源(因为设置了分离属性)**ret = pthread_create (&pt_2, NULL, pthread_func_2, NULL);   if (ret != 0)   {   perror ("pthread_2_create");   }   **//线程二就得等到pthread_join来释放系统资源(因为没有设置分离属性,需要依赖主线程释放资源)**pthread_join (pt_2, NULL);   return 0;   
}   static void pthread_func_1 (void)   
{   int i = 0;   for (; i < 6; i++)   {    printf ("This is pthread_1.\n");   if (i == 2)   {   pthread_exit (0);   }   }   return;   
}   static void pthread_func_2 (void)   
{   int i = 0;   for (; i < 3; i ++)   {   printf ("This is pthread_2.\n");   }   return;   
}

4 注意内存泄漏问题

在使用pthread_create函数创建线程时,默认情况下线程是非分离属性的,其分离属性由pthread_create函数的第二个参数决定。在非分离的情况下,当一个线程结束时,它所占用的系统资源并没有完全释放,也没有真正终止。

  • 只有在调用pthread_join函数并在其返回时,该线程才会释放自己的资源。
  • 或者在设置为分离属性的情况下,一个线程结束会立即释放它所占用的资源。

为了确保在创建线程后避免内存泄漏,必须规范地使用pthread_create,具体做法是设置线程为分离属性。以下是一个示例代码:

void run() {return;
}int main(){pthread_t thread;           // 创建线程idpthread_attr_t attr;        // 设置线程属性pthread_attr_init(&attr);    // 初始化线程属性pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 设置分离属性// 也可以使用 pthread_attr_setdetachstate(&attr, 1); 来设置分离属性pthread_create(&thread, &attr, run, 0); // 第二个参数决定了分离属性// ......return 0;
}

通过设置线程为分离属性,可以确保在线程结束时即刻释放其占用的资源,有效地防止内存泄漏问题。

5 总结

本文深入探讨了线程和进程的概念,以及它们之间的关键区别。通过一个简单而生动的比喻,将进程比喻为火车,线程比喻为火车的车厢,为读者提供了直观的理解。总体而言,深入理解线程和进程的概念,并掌握基础线程创建和属性设置,对于并发编程和多线程应用的开发至关重要。通过本文的阐述,读者将更好地理解这些概念,并能够在实际应用中更有效地利用线程和进程的优势。

参考

  • 线程属性pthread_attr_t简介_猴子居士的博客-CSDN博客_pthread_attr_t详解

  • pthread详解_networkhunter的博客-CSDN博客

  • [C++]多线程: 教你写第一个线程_cn_wk的专栏-CSDN博客_c++怎么写多线程

  • C++ 多线程 | 菜鸟教程 (runoob.com)

  • 编译条件“-lpthread”应该加在makefile的哪里阿?-CSDN社区

  • Darknet yolov3 Makefile文件解析_To Be Continue-CSDN博客

  • 多线程之pthread_create()函数_wushuomin的博客-CSDN博客_pthread_create

http://www.wooajung.com/news/26347.html

相关文章:

  • 杭州网站设计建设公司珠海做网站的公司
  • 赣州网站建设流程汉川seo推广
  • 网站制作公司-山而产品50个关键词
  • 淘宝网店网站建设目的媒体营销
  • 永兴县网站建设哪个好seo网站怎么优化
  • 网站规划包括哪些方面互联网推广好做吗
  • vps空间如何做网站备份最优化方法
  • 个人做广播网站需要注意什么东莞百度网站排名优化
  • 政务公开做的好的网站有哪些百度识图找原图
  • asp.net 做网站实例网络平台有哪些?
  • 做石油期货看什么网站灰色关键词排名优化
  • 网站建设的基本步骤信息流优化师工作内容
  • 比较厉害的网站制作公司百度关键词竞价价格查询
  • 制作一个链接网站网站设计就业
  • 铜川网站建设哪家好网站注册信息查询
  • 专业的常州做网站百度搜索排名服务
  • 松江工业区网站建设千峰培训出来好就业吗
  • 谁用腾讯风铃做网站的哪里有网站推广优化
  • 公司网站开发制作网络推广的网站有哪些
  • 网站建设中模版百度推广点击软件
  • 做app网站的软件叫什么名字超级优化空间
  • 上海网站设计排名拉人注册给佣金的app
  • wordpress 百度pingwindows优化大师值得买吗
  • 朋友圈发布到wordpress引擎优化是什么工作
  • 住建网是个什么网站武汉seo百度
  • 如何生成自己的小程序青岛网络seo公司
  • 网站建设除了中企动力seo入门基础知识
  • 电子商务网站建设李洪心课后答案网店推广软文范例
  • 做视频网站盈利多少百度手机版网页
  • http网站跳转怎么做盛大游戏优化大师