pthread

条件变量生产者和消费者模型

北战南征 提交于 2019-12-31 03:29:47
生产者消费者条件变量模型 线程同步典型的案例即为生产者消费者模型,而借助条件变量来实现这一模型,是比较常见的一种方法。假定有两个线程,一个模拟生产者行为,一个模拟消费者行为。两个线程同时操作一个共享资源(一般称之为汇聚),生产向其中添加产品,消费者从中消费掉产品。 #include <stdlib.h> #include <unistd.h> #include <pthread.h> struct msg { struct msg *next; int num; }; struct msg *head; //静态初始化 一个条件变量 和 一个互斥变量 可以代替init函数 pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; void *consumer(void *p) { struct msg *mp; for (;;) { pthread_mutex_lock(&lock); while (head == NULL) { //头指针为空,说明没有节点 pthread_cond_wait(&has_product, &lock); } mp = head; head = mp->next; //模拟消费掉一个产品

ubutu 12.04

佐手、 提交于 2019-12-29 18:04:29
1、【系统设置】->【外观】->【行为】->【自动隐藏启动器】,隐藏左侧边栏后,可以按快捷键【CTRL+a】弹出侧边栏。 2、QtCreator调试,提示【ptrace不允许的操作】解决方法: sudo vi /etc/sysctl.d/10-ptrace.conf 设置 kernel.yama.ptrace_scope = 0 重启电脑有效。 3、Qt Creator编译线程程序 undefined reference to `pthread_create’ 之前使用GCC的时候编写线程程序会遇到这个问题, 加上-lpthread就搞定了 但是这次是 QT创建的项目,我就不清楚在哪里添加命令行的 , 搞的我到处搜, 在百度搜了几页 唉 无结果呀!!! 于是Google了一下 找到了一句“ QMAKE_CXXFLAGS+=-std=c++0x LIBS+=-pthread ” 但是文章没有说把他添加到QT哪里, 结果我就以为 又失败了。 结果我在项目中看到了 构造步骤,在qmake额外参数填入 QMAKE_CXXFLAGS+=-std=c++0x LIBS+=-pthread 就行了。 源文地址: http://www.krabs.co/cpp/1305.html 来源: https://www.cnblogs.com/sheshiji/p/3701368.html

互斥锁pthread_mutex_init()函数

↘锁芯ラ 提交于 2019-12-28 04:29:49
linux下为了多线程同步,通常用到锁的概念。 posix下抽象了一个锁类型的结构:ptread_mutex_t。通过对该结构的操作,来判断资源是否可以访问。顾名思义,加锁(lock)后,别人就无法打开,只有当锁没有关闭(unlock)的时候才能访问资源。 即对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。 使用互斥锁(互斥)可以使线程按顺序执行。通常,互斥锁通过确保一次只有一个线程执行代码的临界段来同步多个线程。互斥锁还可以保护单线程代码。 要更改缺省的互斥锁属性,可以对属性对象进行声明和初始化。通常,互斥锁属性会设置在应用程序开头的某个位置,以便可以快速查找和轻松修改。 l 头文件: #include <pthread.h> l 函数原型: int pthread_mutex_init( pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr); pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER ; l 函数作用: 该函数用于C函数的多线程编程中,互斥锁的初始化。 pthread_mutex_init () 函数是以动态方式创建互斥锁的

Linux多线程3-3_线程取消

爷,独闯天下 提交于 2019-12-27 01:05:01
一、线程取消 将正在运行的线程取消执行,一个线程可以取消另一个线程,线程也可以自己取消自己。当线程被取消之后,会调用清理函数 二、取消函数 int pthread_cancel(pthread_t tid) 取消tid指定的线程,成功返回0。但是取消只是发送一个请求,并不意味着等待线程终止,而且发送成功也不意味着tid一定会终止 三、取消状态 1、概念 取消状态,就是线程对取消信号的处理方式,忽略或者响应。线程创建时默认响应取消信号 2、函数 int pthread_setcancelstate(int state, int *oldstate) 设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)和PTHREAD_CANCEL_DISABLE,分别表示收到信号后设为CANCLED状态和忽略CANCEL信号继续运行;old_state如果不为NULL则存入原来的Cancel状态以便恢复。 四、取消类型 1、概念 取消类型,是线程对取消信号的响应方式,立即取消或者延时取消。线程创建时默认延时取消 2、函数 int pthread_setcanceltype(int type, int *oldtype) 设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL

Linux多线程3-4_向线程发送信号

我的梦境 提交于 2019-12-27 00:45:48
一、发送信号的函数 int pthread_kill(pthread_t thread, int sig); 1、别被名字吓到,pthread_kill可不是kill,而是向线程发送signal。还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用sigaction()去抓信号并加上处理函数。 ​ 2、向指定ID的线程发送sig信号,如果线程代码内不做处理,则按照信号默认的行为影响整个进程,也就是说,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal处理函数,则整个进程退出。如果要获得正确的行为,就需要在线程内实现sigaction了。所以,如果int sig的参数不是0,那一定要清楚到底要干什么,而且一定要实现线程的信号处理函数,否则,就会影响整个进程。如果int sig是0呢,这是一个保留信号,其实并没有发送信号,作用是用来判断线程是不是还活着。 二、信号处理 1、进程信号处理: int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 给信号signum设置一个处理函数,处理函数在sigaction中指定 act.sa_mask 信号屏蔽字 act.sa_handler 信号集处理程序 ​ 2、信号集的处理 ​ int

Linux多线程3-5_线程清理操作

孤街醉人 提交于 2019-12-27 00:04:32
一、概念 1、线程可以安排它退出时的清理操作,这与进程的可以用atexit函数安排进程退出时需要调用的函数类似。这样的函数称为线程清理处理程序。线程 可以建立多个清理处理程序,处理程序记录在栈中,所以这些处理程序执行的顺序与他们注册的顺序相反 pthread_cleanup_push(void ( rtn)(void ), void *args)//注册处理程序 pthread_cleanup_pop(int excute)//清除处理程序 2、当执行以下操作时调用清理函数,清理函数的参数由args传入 1)、调用pthread_exit 2)、响应取消请求 3)、用非零参数调用pthread_cleanup_pop 3、清理函数的必要性 也许你会认为线程不需什么清理操作,我可以在退出之前把所有该办的事情办了。但是,你不能确保你的线程永远正常的退出,加入它被取消呢。 清理操作的优越性就在于,如果线程被取消了,那么清理函数会自动调用,这一点你是办不到的 4、清理函数要注意 pthread_cleanup_push() 和 pthread_cleanup_pop()是用宏定义继承的,宏定义中包含{},因此他们两要成对出席那 四、实例 return返回的线程不会执行清理操作,以非0参数调用pthread_cleanup_pop或者用pthread_exit退出的线程会执行清理操作 /*

Linux多线程4-1_互斥量

 ̄綄美尐妖づ 提交于 2019-12-26 23:41:15
一、为什么要使用互斥量 1、当多个线程共享相同的内存时,需要每一个线程看到相同的视图。当一个线程修改变量时,而其他线程也可以读取或者修改这个变量,就需要对 这些线程同步,确保他们不会访问到无效的变量 2、在变量修改时间多于一个存储器访问周期的处理器结构中,当存储器的读和写这两个周期交叉时,这种潜在的不一致性就会出现。当然这与处理 器相关,但是在可移植的程序中并不能对处理器做出任何假设 二、互斥量的初始化 1、为了让线程访问数据不产生冲突,这要就需要对变量加锁,使得同一时刻只有一个线程可以访问变量。互斥量本质就是锁,访问共享资源前对 互斥量加锁,访问完成后解锁 2、当互斥量加锁以后,其他所有需要访问该互斥量的线程都将阻塞 3、当互斥量解锁以后,所有因为这个互斥量阻塞的线程都将变为就绪态,第一个获得cpu的线程会获得互斥量,变为运行态,而其他线程会继续 变为阻塞,在这种方式下访问互斥量每次只有一个线程能向前执行 4、互斥量用pthread_mutex_t类型的数据表示,在使用之前需要对互斥量初始化 1)、如果是动态分配的互斥量,可以调用pthread_mutex_init()函数初始化 2)、如果是静态分配的互斥量,还可以把它置为常量PTHREAD_MUTEX_INITIALIZER 3)、动态分配的互斥量在释放内存之前需要调用pthread_mutex_destroy() ​ int

Linux多线程4-2_读写锁

老子叫甜甜 提交于 2019-12-26 23:12:26
一、读写锁的概念 1、读写锁与互斥量类似,不过读写锁有更高的并行性。互斥量要么加锁要么不加锁,而且同一时刻只允许一个线程对其加锁。对于一个变量的读取, 完全可以让多个线程同时进行操作 2、pthread_rwlock_t rwlock 读写锁有三种状态,读模式下加锁,写模式下加锁,不加锁。一次只有一个线程可以占有写模式下的读写锁,但是多个线程可以同时占有读模式的 读写锁 3、读写锁在写加锁状态时,在它被解锁之前,所有试图对这个锁加锁的线程都会阻塞。读写锁在读加锁状态时,所有试图以读模式对其加锁的线程 都会获得访问权,但是如果线程希望以写模式对其加锁,它必须阻塞直到所有的线程释放锁。当读写锁一读模式加锁时,如果有线程试图以写模式对 其加锁,那么读写锁会阻塞随后的读模式锁请求。这样可以避免读锁长期占用,而写锁达不到请求。 4、读写锁非常适合对数据结构读次数大于写次数的程序,当它以读模式锁住时,是以共享的方式锁住的;当它以写模式锁住时,是以独占的模式锁 住的。 二、读写锁的初始化 1、读写锁在使用之前必须初始化 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); 2、 使用完需要销毁 int pthread_rwlock_destroy

无名信号量在多线程间的同步

喜夏-厌秋 提交于 2019-12-26 11:04:01
//无名信号量的常见用法是将要保护的变量放在sem_wait和sem_post中间所形成的临界区内,这样该变量就会被//保护起来,例如: #include <pthread.h> #include <semaphore.h> #include <sys/types.h> #include <stdio.h> #include <unistd.h> int number; // 被保护的全局变量 sem_t sem_id; void* thread_one_fun(void *arg) { sem_wait(&sem_id); printf("thread_one have the semaphore\n"); number++; printf("number = %d\n",number); sem_post(&sem_id); } void* thread_two_fun(void *arg) { sem_wait(&sem_id); printf("thread_two have the semaphore \n"); number--; printf("number = %d\n",number); sem_post(&sem_id); } int main(int argc,char *argv[]) { number = 1; pthread_t id1, id2;

ubuntu 上使用valgrind

老子叫甜甜 提交于 2019-12-25 14:06:14
  Valgrind是一个GPL的软件,用于Linux(For x86, amd64 and ppc32)程序的内存调试和代码剖析。你可以在它的环境中运行你的程序来监视内存的使用情况,比如C 语言中的malloc和free或者 C++中的new和 delete。使用Valgrind的工具包,你可以自动的检测许多内存管理和线程的bug,避免花费太多的时间在bug寻找上,使得你的程序更加稳固。   Valgrind的主要功能   Valgrind工具包包含多个工具,如Memcheck,Cachegrind,Helgrind, Callgrind,Massif。下面分别介绍个工具的作用: Memcheck 工具主要检查下面的程序错误:   1.使用未初始化的内存 (Use of uninitialised memory)   2.使用已经释放了的内存 (Reading/writing memory after it has been free’d)   3.使用超过 malloc分配的内存空间(Reading/writing off the end of malloc’d blocks)   4.对堆栈的非法访问 (Reading/writing inappropriate areas on the stack)   5.申请的空间是否有释放 (Memory leaks – where