Linux多线程编程
线程概念
线程是指运转中的法式的调剂单元。一个线程指的是进程中一个单一顺序的控制流,也被称为轻量级线程。它是系统自力调剂和分派的根基单元。同一进程中的多个线程将同享该系统中的全数系统资本,比如文件描写符和信号处置等。一个进程可以有很多线程,每个线程并行履行分歧的使命。
线程与进程比力
① 和进程相比,它是一种很是“俭仆”的多使命操纵方式。在Linux系统中,启动一个新的进程必须分派给它自力的地址空间,建立众多的数据表来保护其代码段、仓库段和数据段,这类多使命工作方式的价格很是“高贵”。而运转于一个进程中的多个线程,它们相互之间利用不异的地址空间,同享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且线程间相互切换所需要时候也远远小于进程间切换所需要的时候。
② 线程间方便的通讯机制。对分歧进程来说它们具有自力的数据空间,要停止数据的传递只能经过通讯的方式停止。这类方式不但费时,而且很不方便。线程则否则,由于同一进程下的线程之间同享数据空间,所以一个线程的数据可以间接为其他线程所用,不但方便,而且快速。
线程根基编程
Linux系统下的多线程遵守POSIX线程接口,称为pthread。编写Linux下的多线程法式,需要利用头文件pthread.h,毗连时需要利用库libpthread.a。由于pthread的库不是Linux系统的库,所以在编译时要加上 -lpthread。例如:gcc filename -lpthread。留意,这里要讲的线程相关操纵都是用户空间中的线程的操纵。
线程建立:建立线程现实上就是肯定挪用该线程函数的进口点,这里凡是利用的函数是pthread_create()。在线程建立后,就起头运转相关的线程函数。
线程退出:在线程建立后,就起头运转相关的线程函数,在该函数运转完以后,该线程也就退出了,这也是线程退出的一种方式。另一种退出线程的方式是利用函数pthread_exit(),这是线程的自动行为。这里要留意的是,在利用线程函数时,不能随意利用exit()退出函数来停止出错处置。由于exit()的感化是使挪用进程停止,而一个进程常常包括多个线程,是以,在利用exit()以后,该进程中的一切线程都停止了。在线程中便可以利用pthread_exit()来取代进程中的exit()。
线程期待:由于一个进程中的多个线程是同享数据段的,是以,凡是在线程退出后,退出线程所占用的资本并不会随着线程的停止而获得开释。正如进程之间可以用wait()系统挪用来同步停止并开释资本一样,线程之间也有类似机制,那就是pthread_join()函数。pthread_join()用于将当进步程挂起来期待线程的竣事。这个函数是一个线程阻塞的函数,挪用它的函数将一向期待到被期待的线程竣事为止,当函数返回时,被期待线程的资本就被发出。
线程取消:前面已经提到线程挪用pthread_exit()函数自动停止本身线程,可是在很多线程利用中,经常会碰到在此外线程中要停止另一个线程的题目,此时挪用pthread_cancel()函数来实现这类功用,但在被取消的线程的内部需要挪用pthread_setcancel()函数和pthread_setcanceltype()函数设备自己的取消状态。例如,被取消的线程接收到另一个线程的取消请求以后,是接管函数疏忽这个请求;假如是接管,则再判定立即采纳停止操纵还是期待某个函数的挪用等。
线程标识符获得:获得挪用线程的标识ID。
线程断根:线程停止有两种情况:一般停止和非一般停止。线程自动挪用pthread_exit()大概从线程函数中return都将使线程一般退出,这是可预见的退出方式;非一般停止是线程在别的线程的干涉下,大概由于本身运转出错(比如拜候不法地址)而退出,这类退出方式是不成预见的。非论是可预见的线程停止还是异常停止,都回存在资本开释的题目,若何保证线程停止时能顺遂地开释掉自己所占用的资本,是一个必须斟酌的题目。
从pthread_cleanup_push()的挪用点到pthread_cleanup_pop()之间的法式段中的停止行动(包括挪用pthread_exit()和异常停止,不包括return)都将履行pthread_cleanup_push()所指定的清算函数。
1、若何操纵2个条件变量实现线程同步?
思绪:就是往返的操纵pthread_cond_signal()函数,当一方被阻塞时,叫醒函数可以叫醒pthread_cond_wait()函数,只不外pthread_cond_wait()这个方式要履行厥后的语句,必须碰到下一个阻塞(也就是pthread_cond_wait()方式时),才履行叫醒后的厥后语句。
代码以下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define MAX_NUM 2static int count = 1;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t js = PTHREAD_COND_INITIALIZER;pthread_cond_t os = PTHREAD_COND_INITIALIZER;void* A(void *arg){
pthread_mutex_lock(&mutex);
while(count <= MAX_NUM)
{
if(count%2 == 1){
printf("A = %d\n", count);
count++;
pthread_cond_signal(&os);
sleep(5);
printf("bbbbbbbbbbbbbbbbbbbbbbbbbbb\n");
}else{
printf("ccccccccccccccccccccccccccc\n");
pthread_cond_wait(&js, &mutex);
printf("ddddddddddddddddddddddddddd\n");
}
pthread_mutex_unlock(&mutex);
}}
void* B(void *arg)
{
pthread_mutex_lock(&mutex);
while(count <= MAX_NUM){
if(count%2 == 0){
printf("B = %d\n", count);
count++;
pthread_cond_signal(&js);
}
else
{
pthread_cond_wait(&os, &mutex);
printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
}
}
pthread_mutex_unlock(&mutex);
}
int main(void)
{
pthread_t tid1, tid2;
pthread_create(&tid2, NULL, B, NULL);
sleep(1);
pthread_create(&tid1, NULL, A, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
} 运转成果
上面的这个法式就是:2个条件变量对一个互斥量的操纵。signal()发送叫醒wait(),wait()以后的语句临时不履行,直到下一次碰到wait()时,阻塞,返回履行叫醒的wait()以后的语句。
2、怎样建立10个线程的起头运转和竣事进程?
操纵2个条件变量和1个互斥量即可实现。
代码以下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;void* thread_fun1(void *arg){
int i = *(int *)arg;
pthread_mutex_lock(&mutex);
printf("[%d] thread start up\n", i);
pthread_cond_wait(&cond, &mutex);
printf("[%d]thread is wake up\n", i);
pthread_mutex_unlock(&mutex);
}
void* thread_fun2(void *arg)
{
pthread_cond_broadcast(&cond); //广播,一次叫醒一切的线程}int main(void){
pthread_t tid1[10], tid2;
int i;
for(i = 0; i < 10; i++)
{
pthread_create(&tid1, NULL, thread_fun1, &i);//建立10个线程
sleep(1);
}
pthread_create(&tid2, NULL, thread_fun2, NULL);//建立1个线程
for(i = 0; i < 10; i++)
{ //主线程等子线程履行完
pthread_join(tid1, NULL);
}
pthread_join(tid2, NULL);
return 0;
} 运转成果
多线程的编程中:互斥量、条件变量是重中之重!!!
更多linux背景开辟免费视频材料获得 背景私信【架构】
|
温馨提示:
好向圈www.kuaixunai.com是各行业经验分享交流社区,你可以在这里发布交流经验,也可以发布需求与服务,经验圈子里面禁止带推广链接、联系方式、违法词等,违规将封禁账号,相关产品信息将永久不予以通过,同时有需要可以发布在自己的免费建站官网里面或者广告圈, 下载好向圈APP可以加入各行业交流群
本文不代表好向圈的观点和立场,如有侵权请下载好向圈APP联系在线客服进行核实处理。
审核说明:好向圈社区鼓励原创内容发布,如果有从别的地方拷贝复制将不予以通过,原创优质内容搜索引擎会100%收录,运营人员将严格按照上述情况进行审核,望告知!
|