当前位置: 首页 > 科技观察

Linuxmutex的线程互斥

时间:2023-03-12 00:02:34 科技观察

在编程中,为了保证共享数据操作的完整性,引入了对象互斥的概念。每个对象对应一个标记,可以称为“互斥锁”,用来保证在任何时候只有一个线程可以访问该对象。Linux实现的互斥锁机制包括POSIX互斥锁和内核互斥锁。本文主要讲POSIX互斥锁,即线程间互斥锁。》信号量用于多线程、多任务同步,当一个线程完成某个动作后,会通过信号量告诉其他线程,其他线程会执行一些动作(大家都在sem_wait的时候阻塞在那里)。互斥锁用在多线程、多任务互斥中,如果一个线程占用了某个资源,其他线程就无法访问,直到这个线程解锁,其他线程才能开始使用这个资源,比如对于全局变量对于访问,有时需要加锁,操作完成后,再解锁。有时锁和信号量会同时使用。也就是说,信号量不一定锁定某个资源,而是进程的概念,例如:有两个线程,A和B,B线程需要等待A线程完成一个在执行下面的步骤之前一定要执行某个任务。这个任务不一定是锁定某个资源,也可以进行一些计算或者数据处理。线程互斥量就是“锁定某个资源”的概念。在锁定期间,其他线程不能对受保护的数据进行操作。在某些情况下两者是可以互换的。两者的区别:scopesemaphore:进程间或线程间(linux只有线程间)信号量的值大于0,其他线程可以sem_wait成功,成功后的信号量的值减一,如果值不大于0,sem_wait会阻塞,直到sem_posti后该值加一发布了。总之,信号量的值>=0。Mutex:只要被锁定,其他线程就不能访问受保护的资源。如果没有锁,则资源获取成功,否则阻塞等待资源可用。总之,threadmutex的vlaue可以是负数。多线程线程是计算机中独立运行的最小单元,运行时占用的系统资源很少。与多进程相比,多进程具有一些多进程所没有的优点。最重要的是:对于多线程来说,比多进程更能节省资源。线程是在Linux中创建的。新创建的线程不在原来的进程中,而是系统通过一个系统调用clone()。系统复制了一个与原进程一模一样的进程,并在这个进程中执行线程函数。在Linux中,线程的创建是通过函数pthread_create()函数实现的:pthread_create()intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*st其中:thread表示一个pthread_t类型的指针;attr用于指定线程的一些属性;start_routine表示一个函数指针,是线程调用函数;arg表示传递给线程调用函数的参数,当线程创建成功时,函数pthread_create()返回0,如果返回值为not0表示创建线程失败,对于线程的属性,定义在结构体pthread_attr_t中,线程创建过程如下:#include#include#include#includevoid*thread(void*id){pthread_tnewthid;newthid=pthread_self();printf("thisisanewthread,threadIDis%u\n",newthid);returnNULL;}intmain(){intnum_thread=5;pthread_t*pt=(pthread_t*)malloc(sizeof(pthread_t)*num_thread);printf("mainthread,IDis%u\n",pthread_self());for(inti=0;i#include#include#includevoid*thread(void*id){pthread_tnewthid;newthid=pthread_self();intnum=*(int*)id;printf("thisisanewthread,threadIDis%u,id:%d\n",newthid,num);returnNULL;}intmain(){//pthread_tthid;intnum_thread=5;pthread_t*pt=(pthread_t*)malloc(sizeof(pthread_t)*num_thread);int*id=(int*)malloc(sizeof(int)*num_thread);printf("mainthread,IDis%u\n",pthread_self());for(inti=0;i#include#include#includevoid*thread(void*id){pthread_tnewthid;newthid=pthread_self();intnum=*(int*)id;printf("thisisanewthread,threadIDis%u,id:%d\n",newthid,num);printf("thread%uisdone\n",newthid);returnNULL;}intmain(){intnum_thread=5;pthread_t*pt=(pthread_t*)malloc(sizeof(pthread_t)*num_thread);int*id=(int*)malloc(sizeof(int)*num_thread);printf("mainthread,IDis%u\n",pthread_self());for(inti=0;i#include#includeconstcharfilename[]="hello";void*thread(void*id){intnum=*(int*)id;//写入文件的操作FILE*fp=fopen(filename,"a+");intstart=*((int*)id);intend=start+1;setbuf(fp,NULL);//设置缓冲区的大小fprintf(stdout,"%d\n",start);for(inti=(start*10);i<(end*10);i++){fprintf(fp,"%d\t",i);}fprintf(fp,"\n");fclose(fp);returnNULL;}intmain(){intnum_thread=5;pthread_t*pt=(pthread_t*)malloc(sizeof(pthread_t)*num_thread);int*id=(int*)malloc(sizeof(int)*num_thread);for(inti=0;i#include#includepthread_mutex_tmutex;constcharfilename[]="hello";void*thread(void*id){intnum=*(int*)id;//锁定if(pthread_mutex_lock(&mutex)!=0){fprintf(stdout,"lockerror!\n");}//写入文件的操作FILE*fp=fopen(filename,"a+");intstart=*((int*)id);intend=start+1;setbuf(fp,NULL);//设置大小缓冲区fprintf(stdout,"%d\n",start);for(inti=(start*10);i<(end*10);i++){fprintf(fp,"%d\t",i);}fprintf(fp,"\n");fclose(fp);//解锁pthread_mutex_unlock(&mutex);returnNULL;}intmain(){intnum_thread=5;pthread_t*pt=(pthread_t*)malloc(sizeof(pthread_t)*num_thread);int*id=(int*)malloc(sizeof(int)*num_thread);//初始化互斥量if(pthread_mutex_init(&mutex,NULL)!=0){//互斥量初始化失败free(pt);free(id);return1;}for(inti=0;i