网站空间多大,wordpress修改自己的头像,物流业网站建设方案实验总结,宝塔 怎么做网站初始化条件变量
int pthread_cond_init(pthread_cond_t *cond,const pthread_condattr_t *attr);
返回值#xff1a;函数成功返回0#xff1b;任何其他返回值都表示错误
初始化一个条件变量。当参数attr为空指针时#xff0c;函数创建的是一个缺省的条件变量。
阻塞
in…初始化条件变量
int pthread_cond_init(pthread_cond_t *cond,const pthread_condattr_t *attr);
返回值函数成功返回0任何其他返回值都表示错误
初始化一个条件变量。当参数attr为空指针时函数创建的是一个缺省的条件变量。
阻塞
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
wait需要传入已经lock的mutex变量。进入wait函数会自动解锁mutex参数指向的互斥锁并使当前线程阻塞在cond参数指向的条件变量上。当线程被唤醒退出wait函数时会自动对锁再次进行加锁成功后返回。
被阻塞的线程可以被pthread_cond_signal函数pthread_cond_broadcast函数唤醒。一般一个条件表达式都是在一个互斥锁的保护下被检查。当条件表达式未被满足时线程将仍然阻塞在这个条件变量上。当另一个线程改变了条件的值并向条件变量发出信号时等待在这个条件变量上的一个线程或所有线程被唤醒接着都试图再次占有相应的互斥锁。
int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, const structtimespec * abstime);
函数到了一定的时间即使条件未发生也会解除阻塞。这个时间由参数abstime指定。
唤醒
int pthread_cond_signal(pthread_cond_t *cond);
函数被用来释放被阻塞在指定条件变量上的一个线程。唤醒阻塞在条件变量上的所有线程的顺序由调度策略决定如果线程的调度策略是SCHED_OTHER类型的系统将根据线程的优先级唤醒线程。
int pthread_cond_broadcast(pthread_cond_t *cond);
函数唤醒所有被pthread_cond_wait函数阻塞在某个条件变量上的线程参数cond被用来指定这个条件变量。
释放条件变量
int pthread_cond_destroy(pthread_cond_t *cond);
一个例子
#include stdio.h#include pthread.h#include unistd.hpthread_mutex_t count_lock;pthread_cond_t count_nonzero;unsigned count 0;void *decrement_count(void *arg){pthread_mutex_lock(count_lock);printf(decrement_count get count_lock/n);while(count 0){printf(decrement_count count 0 /n);printf(decrement_count before cond_wait /n);pthread_cond_wait(count_nonzero, count_lock);printf(decrement_count after cond_wait /n);}count count - 1;pthread_mutex_unlock(count_lock);}void *increment_count(void *arg){pthread_mutex_lock(count_lock);printf(increment_count get count_lock /n);if(count 0){printf(increment_count before cond_signal /n);pthread_cond_signal(count_nonzero);printf(increment_count after cond_signal /n);}count count 1;pthread_mutex_unlock(count_lock);}int main(void){pthread_t tid1, tid2;pthread_mutex_init(count_lock, NULL);pthread_cond_init(count_nonzero, NULL);pthread_create(tid1, NULL, decrement_count, NULL);sleep(2);pthread_create(tid2, NULL, increment_count, NULL);sleep(10);pthread_exit(0);return 0;}
运行结果
decrement_count get count_lock decrement_count count 0 decrement_count before cond_wait increment_count get count_lock increment_count before cond_signal increment_count after cond_signal decrement_count after cond_wait
调试程序的运行过程
1、开始时 counter 为0 main
2、首先生成一个thrd1线程运行decrement_counter(),此线程内函数运行流程为:
先锁定 互斥锁count_lock 如果counter为0,此线程被阻塞在条件变量count_nonzero上.同时释放互斥锁count_lockwait函数内部会先释放锁等待signal激活后自动再加上锁.
3、与此同时主程序还在运行,创建另一个线程thrd2运行 increment_counter,此线程内的函数流程如下:
先锁定 互斥锁count_lockwait内部释放锁的互斥锁 如果counter为0, 唤醒在条件变量count_nonzero上的线程即thrd1.但是由于互斥锁count_lock被当前thrd2锁住signal激活后线程1的wait内部需要对count_lock上锁, thrd1还是在等待. 然后thrd2中对count1,释放互斥锁。此时thrd1由于互斥锁释放得以运行,重新判断counter是不是为0,如果为0再把线程阻塞在条件变量count_nonzero上,但这时counter已经为1了.所以线程继续运行.counter-1释放互斥锁退出后运行主线程main
生产者消费者例子
#include unistd.h
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h#include stdlib.h
#include stdio.h
#include errno.h
#include string.h
#include pthread.h#define ERR_EXIT(m)\do \{ \perror(m); \exit(EXIT_FAILURE); \}while(0)#define CONSUMERS_COUNT 2
#define PRODUCERS_COUNT 1pthread_mutex_t g_mutex;
pthread_cond_t g_cont;int iread;pthread_t g_thread[CONSUMERS_COUNTPRODUCERS_COUNT];void* produce(void* arg)
{while(1){pthread_mutex_lock(g_mutex);iread; //生产printf(product iread%d\n,iread);pthread_cond_signal(g_cont);printf(produce is produat\n);pthread_mutex_unlock(g_mutex);sleep(3);}return NULL;
}
void* consumer(void* arg)
{while(1){pthread_mutex_lock(g_mutex);printf(consumer iread %d\n,iread); while(iread0) //需要等待生产者生产{pthread_cond_wait(g_cont, g_mutex);printf(iread is changed\n);}iread--; //消费sleep(1);pthread_mutex_unlock(g_mutex);}return NULL;
} int main()
{int i;pthread_mutex_init(g_mutex,NULL);pthread_cond_init(g_cont,NULL);for(i0; i PRODUCERS_COUNT;i){pthread_create(g_thread[i],NULL,produce,(void*)i);}for(i0; i CONSUMERS_COUNT;i){pthread_create(g_thread[i PRODUCERS_COUNT],NULL,consumer,(void*)i);}for(i0; i PRODUCERS_COUNTCONSUMERS_COUNT;i){pthread_join(g_thread[i],NULL);}pthread_mutex_destroy(g_mutex);pthread_cond_destroy(g_cont);return 0;
}