pthread_join与pthread_detach
pthread_join函数会让主线程阻塞,直到所有线程都已经退出。如果没有pthread_join,主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。
pthread_detach()即主线程与子线程分离,子线程结束后,资源自动回收。
image.png image.pngarg可以通过结构体传各类型多个变量数据,pthread_join()获取返回值调用pthread_join()将在pthread_exit()之后一直阻塞自己(有时候为了各线程之间同步,但是会拖后腿),一直到要等待加入的线程运行结束,必须返回一个指针(可以是void*),。
# 下面这个线程没有pthread_join()实现线程同步(互斥访问资源)
#include<pthread.h>
#include<stdio.h>
#define NUM_THREADS 5
void *Print(void * threadid){
long *data=(long*)threadid;
printf("th:%ld\n",*data);
pthread_exit(NULL);
}
int main(){
pthread_t threads[NUM_THREADS];
for(long tid=0;tid<NUM_THREADS;tid++){
pthread_create(&threads[tid],NULL,Print,(void*)&tid);
}
pthread_exit(NULL);
}
gcc p.c -lpthread -o pthread
./pthread
th:2
th:3
th:5
th:4
th:5
# 很明显,没有加入互斥信号,导致资源争抢,相互覆盖对方缓冲区。
需要引用pthread库函数(因为不在当前目录在系统库里)
- 主线程并不希望因为调用pthread_join而阻塞(因为还要继续处理之后到来的链接),这时可以在子线程中加入代码
pthread_detach(pthread_self())
或者父线程调用pthread_detach(thread_id)(非阻塞,可立即返回)
这将该子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源。
void print(void *ptr){
pthread_detach(pthread_self());
// 将状态改为unjoinable,保证资源的释放,pthread_self()返回当前线程的id
......
pthread_exit(0) ;
//pthread_exit时自动会被释放
}
信号:pthread_cond
互斥锁有一个明显到缺点: 只有两种状态,锁定和非锁定。而条件变量则通过允许线程阻塞并等待另一个线程发送唤醒信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用(因为使用到的标记也可能是共享变量需要加互斥锁)。
函数将解锁mutex参数指向的互斥锁,并使当前线程阻塞在cv参数指向的条件变量上。被阻塞的线程可以被pthread_cond_signal函数,pthread_cond_broadcast函数唤醒,也可能在被信号中断后被唤醒。
cv=pthread_cond_init();
pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex);
pthread_cond_signal(&cv);
pthread_cond_broadcast(&cv)
void *inc_count(void *idp)
{
int i = 0;
int taskid = 0;
int *my_id = (int*)idp;
for (i=0; i<TCOUNT; i++) {
pthread_mutex_lock(&count_mutex);
taskid = count;
count++;
/*
唤醒一个阻塞在该条件变量到线程
如果没有线程被阻塞在条件变量上,那么调用pthread_cond_signal()将没有作用
*/
pthread_cond_signal(&count_threshold_cv);
printf("inc_count(): thread %d, count = %d, unlocking mutex\n", *my_id, count);
pthread_mutex_unlock(&count_mutex);
sleep(1);
}
printf("inc_count(): thread %d, Threshold reached.\n", *my_id);
pthread_exit(NULL);
}
网友评论