int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)

其中cond是一个指向结构pthread_cond_t的指针,cond_attr是一个指向结构pthread_condattr_t的指针。结构 pthread_condattr_t是条件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用, 默认值是PTHREAD_ PROCESS_PRIVATE即此条件变量被同一进程内的各个线程使用。

注意初始化条件变量只有未被使用时才能重新初始化或被释放。释放一个条件变量的函数为pthread_cond_destroy(pthread_cond_t cond)。

也可以静态的初始化条件变量

pthread_cond_t my_condition = PTHREAD_COND_INITIALIZER;

pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t *attr);
// 初始化锁变量mutex。
// attr为锁属性,NULL值为默认属性。

pthread_mutex_lock(pthread_mutex_t *mutex);
// 加锁(阻塞操作)

pthread_mutex_trylock(pthread_mutex_t *mutex);
// 试图加锁(不阻塞操作)
// 当互斥锁空闲时将占有该锁;否则立即返回
// 但是与2不一样的是当锁已经在使用的时候,返回为EBUSY,而不是挂起等待。

pthread_mutex_unlock(pthread_mutex_t *mutex);
释放锁

pthread_mutex_destroy(pthread_mutex_t *mutex);
销毁一个不再需要的互斥量,释放系统资源。

pthread_cond_wait() / pthread_cond_timedwait -----等待条件变量,挂起线程,区别是后者,会有timeout时间,
如果到了timeout,线程自动解除阻塞,这个时间和 time()系统调用相同意义的。以1970年时间算起。

pthread_cond_signal ----激活等待列表中的线程,

pthread_cond_broadcast() -------激活所有等待线程列表中最先入队的线程

条件变量

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:

  • 1)一个线程等待"条件变量的条件成立"而挂起;
  • 2)另一个线程使"条件成立"(给出条件成立信号)。

为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

注意:

  • 1)上面这几个函数都是原子操作,可以为理解为一条指令,不会被其他程序打断

  • 2)上面这个几个函数,必须配合使用。

  • 3)pthread_cond_wait,先会解除当前线程的互斥锁,然后挂线线程,等待条件变量满足条件。一旦条件变量满足条件,则会给线程上锁,继续执行pthread_cond_wait

返回值:

pthread_mutex_lock() 和 pthread_mutex_unlock() 返回0,否则返回一个错误的提示码

pthread_mutex_trylock() 在成功获得了一个mutex的锁后返回0,否则返回一个错误提示码错误

pthread_mutex_lock() 和 pthread_mutex_unlock()失败的时候 [EINVAL] mutex在生成的时候,它的protocol属性的值是 PTHREAD_PRIO_PROTECT,同时调用线程的优先级(priority)比该mutex的当前prority上限高


int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

  • 第一个参数为指向线程标识符的指针。
  • 第二个参数用来设置线程属性。
  • 第三个参数是线程运行函数的起始地址。
  • 最后一个参数是运行函数的参数。

https://blog.csdn.net/weibo1230123/article/details/81410241

int pthread_join(pthread_t thread, void **retval); 子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源。

  • thread: 需要等待的线程,指定的线程必须位于当前的进程中,而且不得是分离线程

  • retval: 线程tid所执行的函数返回值(返回值地址需要保证有效),其中status可以为NULL

int pthread_detach(pthread_t tid);

  • 主线程与子线程分离,子线程结束后,资源自动回收。

其他操作

#include <pthread.h>
int pthread_condattr_init(pthread_condattr_t* attr);
int pthread_condattr_destroy(pthread_condattr_t* attr);

//返回值:成功返回0;失败返回错误编码

pthread_condattr_init

  • 功能:对条件变量属性结构体初始化
  • 调用此函数之后,条件变量属性结构体的属性都是系统默认值,如果想要设置其他属性,还需要调用不同的函数进行设置

pthread_condattr_destroy

  • 功能:对条件变量属性结构体反初始化(销毁)
  • 只反初始化,不释放内存

#include <pthread.h>
int pthread_condattr_setshared(pthread_condattr_t* attr,int pshared);
int pthread_condattr_getshared(const pthread_condattr_t* restrict attr,int* restrict pshared);

//返回值:成功返回0;失败返回错误编码

pthread_condattr_setshared

  • 功能:设置条件变量的进程共享属性

pthread_condattr_getshared

  • 功能:获取条件变量的进程共享属性

#include <pthread.h>
int pthread_condattr_setclock(pthread_condattr_t* attr,clockid_t clock_id);
int pthread_condattr_getclock(const pthread_condattr_t* restrict attr,clockid_t *restrict clock_id);

//返回值:成功返回0;失败返回错误编码

pthread_condattr_setclock

  • 功能:此函数用于设置pthread_cond_timewait函数使用的时钟ID

pthread_condattr_getclock

  • 功能:此函数获取可被用于pthread_cond_timedwait函数的时钟ID。pthread_cond_timedwait函数使用前需要用pthread_condattr_t对条件变量进行初始化


Linux 线程库版本

getconf GNU_LIBPTHREAD_VERSION

pthread_create 创建一个线程

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

线程结束

void pthread_exit(void *retval);

线程回收

int pthread_join(pthread_t thread, void **retval);

pthread_join

取消线程

int pthread_cancel(pthread_t thread);

pthread_state

目标线程可以设置是否允许被取消以及如何取消

int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);

setcancelstate

初始化线程属性对象

int pthread_attr_init(pthread_attr_t *attr);

销毁线程属性对象, 被销毁的线程属性对象只有再次初始化之后才能继续使用

int pthread_attr_destroy(pthread_attr_t *attr);

pthread_state

POSIX信号量函数

//初始化一个未命名的信号量
int sem_init(sem_t *sem, int pshared, unsigned int value);
其中sem是要初始化的信号量,pshared表示此信号量是在进程间共享还是线程间共享,value是信号量的初始值。

//用于销毁信号量
int sem_destroy(sem_t *sem);
其中sem是要销毁的信号量。只有用sem_init初始化的信号量才能用sem_destroy销毁。
等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。成功返回0,失败返回-1。

//以原子操作的方式将信号量值减1
int sem_wait(sem_t *sem);

//始终立即返回,不论被操作的信号是否有非0值
int sem_trywait(sem_t *sem);

//以原子操作的方式将信号量的值加1 信号量大于0时 其他正在调用sem_wait等待信号量的线程将被唤醒**
int sem_post(sem_t *sem);
释放信号量,让信号量的值加1。相当于V操作。

互斥锁

//初始化互斥锁
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
    const pthread_mutexattr_t *restrict attr);

//用于销毁互斥锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);

//以原子操作的方式给一个互斥锁加锁
int pthread_mutex_lock(pthread_mutex_t * mutex);

//立即返回 不论被操作的互斥锁是否已经被加锁
int pthread_mutex_trylock(pthread_mutex_t * mutex);

//以原子操作的方式给一个互斥锁解锁
int pthread_mutex_unlock(pthread_mutex_t * mutex);

互斥锁属性

// 初始化互斥锁属性对象
int pthread_mutexattr_init(pthread_mutexattr_t *attr);

//销毁互斥锁属性对象
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);

//获取和设置互斥锁的pshared属性
int pthread_mutexattr_getpshared(const pthread_mutexttr_t * attr, int * pshred);
int pthread_mutexattr_setpshared(pthread_mutex_attr_t * attr, int pshared);

//获取和设置互斥锁的type属性
int pthread_mutexattr_gettype(const pthread_mutexattr_t * attr, int * type);
int pthread_mutexattr_settype(pthread_mutexattr_t * attr, int type);

//确保fork调用后父进程和子进程都拥有一个清楚的锁状态
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));

//1. 在主线程创建出其他子线程之前就调用 pthread_sigmask来设置好信号掩码,所有新创建的子线程都将自动继承这个信号掩码。这样做之后,实际上所有线程都不会响应被屏蔽的信号了。
//设置线程信号掩码
int pthread_sigmask(int how, const sigset_t * restrict set, sigset_t * restrict oset);
//2. 在某个线程中调用如下函数来等待信号并处理之∶
int sigwait(const sigset_t *restrict set, int *restrict sig);

mutex_type

条件变量

//初始化条件变量
int pthread_cond_init(pthread_cond_t *cv, const pthread_condattr_t *cattr);

//销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cv);

//以广播方式唤醒所有等待目标条件变量的线程
int pthread_cond_broadcast(pthread_cond_t *cv);

//释放被阻塞在指定条件变量上的一个线程
int pthread_cond_signal(pthread_cond_t * cond);

//等待目标条件变量
int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex);

进程池和线程池

process_thread more_process_deal


Reference:

https://blog.csdn.net/qq_41453285/article/details/90904870

https://blog.csdn.net/liangxanhai/article/details/7767430

https://blog.csdn.net/wushuomin/article/details/80051295

https://blog.csdn.net/lovecodeless/article/details/24885127

https://blog.csdn.net/weibo1230123/article/details/81410241