线程同步技术

线程同步技术多线程的三种同步机制1,互斥锁;这个感觉只是保护了资源不会被同时使用,至于同步???还没怎么理解。基本函数:通过锁机制实现线程间的同步。同一时刻只允许一个线程执行一个关键部分的代码。int pthread_mutex_init(pthre

多线程的三种同步机制   1,互斥锁;   这个感觉只是保护了资源不会被同时使用,至于同步???还没怎么理解。   基本函数:   通过锁机制实现线程间的同步。同一时刻只允许一个线程执行一个关键部分的代码。   int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr); 或pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER。前者是动态初始化,后者是静态。   int pthread_mutex_lock(pthread_mutex *mutex);   int pthread_mutex_destroy(pthread_mutex *mutex);   int pthread_mutex_unlock(pthread_mutex *   这个用得比较多,不做详细说明。   2,条件变量   条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使”条件成立”(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。   基本函数:   初始化:同互斥锁一样也是两种方式 pthread_cond_t cond=PTHREAD_COND_INITIALIER和int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);   int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex); //等待条件变量   int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime); //延时等待条件变量   int pthread_cond_destroy(pthread_cond_t *cond); //删除条件变量   int pthread_cond_signal(pthread_cond_t *cond); //解除在一个等待的线程阻塞   int pthread_cond_broadcast(pthread_cond_t *cond);  //解除所有线程的阻塞   看个例子:(此例子着重说明pthre_cond_signal/broadcast,如果没有wait,依旧正常返回,并且不会保留到下次wait,通俗点:我解除阻塞的时候,你没有阻塞,那哥们我先走了,下次你阻塞,得等到我下次来解除,过时不候~~)   #include <pthread.h> #include <stdio.h> #include <sys/signal.h> #include <semaphore.h> static pthread_mutex_t vpu_mutex1 = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t vpu_mutex2 = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t vpu_cond1 = PTHREAD_COND_INITIALIZER; static pthread_cond_t vpu_cond2 = PTHREAD_COND_INITIALIZER; void* test_thread1(void *arg) { sleep(2); pthread_mutex_lock(&vpu_mutex1); pthread_cond_signal(&vpu_cond1); pthread_mutex_unlock(&vpu_mutex1); sleep(5); } void* test_thread2(void *arg) { sleep(1); pthread_mutex_lock(&vpu_mutex2); pthread_cond_signal(&vpu_cond2); pthread_mutex_unlock(&vpu_mutex2); sleep(5); } int main() { int i, j, ret; pthread_t test_id1; pthread_t test_id2; ret = pthread_create(&test_id1, NULL, test_thread1, NULL); if (ret != 0) { printf(“Create pthread error!   ”); return -1;//exit(1); } ret = pthread_create(&test_id2, NULL, test_thread2, NULL); if (ret != 0) { printf(“Create pthread error!   ”); return -1; //exit(1); } pthread_mutex_lock(&vpu_mutex1); pthread_cond_wait(&vpu_cond1, &vpu_mutex1); pthread_mutex_unlock(&vpu_mutex1); pthread_mutex_lock(&vpu_mutex2); pthread_cond_wait(&vpu_cond2, &vpu_mutex2); pthread_mutex_unlock(&vpu_mutex2); printf(“hello world   ”); pthread_join(test_id1, NULL); return 0; }   上面的例子是不会打印出hello world的。因为等不到vpu_cond2的接触。如果将test_thread1和test_thread2中的sleep对调,就可以了。 这个简单,将多了就啰嗦了。   说明:      (1)pthread_cond_wait 自动解锁互斥量(如同执行了pthread_unlock_mutex),并等待条件变量触发。这时线程挂起,不占用CPU时间,直到条件变量被触发(变量为ture)。在调用pthread_cond_wait之前,应用程序必须加锁互斥量。pthread_cond_wait函数返回前,自动重新对互斥量加锁(如同执行了pthread_lock_mutex)。       (2)互斥量的解锁和在条件变量上挂起都是自动进行的。因此,在条件变量被触发前,如果所有的线程都要对互斥量加锁,这种机制可保证在线程加锁互斥量和进入等待条件变量期间,条件变量不被触发。条件变量要和互斥量相联结,以避免出现条件竞争——个线程预备等待一个条件变量,当它在真正进入等待之前,另一个线程恰好触发了该条件(条件满足信号有可能在测试条件和调用pthread_cond_wait函数(block)之间被发出,从而造成无限制的等待)。   3,信号量   #include <semaphore.h>   int sem_init (sem_t *sem , int pshared, unsigned int value);         这是对由sem指定的信号量进行初始化,设置好它的共享选项(linux 只支持为0,即表示它是当前进程的局部信号量),然后给它一个初始值VALUE。   两个原子操作函数:   int sem_wait(sem_t *sem);   int sem_post(sem_t *sem);   这两个函数都要用一个由sem_init调用初始化的信号量对象的指针做参数。   sem_post:给信号量的值加1;   sem_wait:给信号量减1;对一个值为0的信号量调用sem_wait,这个函数将会等待直到有其它线程使它不再是0为止。   int sem_getvalue(sem_t *sem, int *sval);   信号的值,存入sval中。   int sem_destroy(sem_t *sem);   这个函数的作用是再我们用完信号量后都它进行清理。归还自己占有的一切资源。   看个例子:跟上面那个一样,但是信号是可以保留的,因为sem_post后,信号量+1,sem_wait信号量-1,即只要sem不为0,一遇wait就向下执行。   #include <pthread.h> #include <stdio.h> #include <sys/signal.h> #include <semaphore.h> sem_t sem_1; sem_t sem_2; void* test_thread1(void *arg) { sleep(3); sem_post(&sem_1); sleep(5); } void* test_thread2(void *arg) { sleep(1); sem_post(&sem_2); sleep(5); } int main(int argc, char argv) { int i, j, ret; sem_init(&sem_1, 0, 0); sem_init(&sem_2, 0, 0); pthread_t test_id1; pthread_t test_id2; ret = pthread_create(&test_id1, NULL, test_thread1, NULL); if (ret != 0) { printf(“Create pthread error!   ”); return -1;//exit(1); } ret = pthread_create(&test_id2, NULL, test_thread2, NULL); if (ret != 0) { printf(“Create pthread error!   ”); return -1; //exit(1); } sem_wait(&sem_1); sem_wait(&sem_2); // sem_getvalue(&single_seq, &sem_value); printf(“hello world   ”); pthread_join(test_id1, NULL); }       通过上面两个例子对比,可得条件变量和信号量的区别。当然如果要使得条件变量,具有信号量的功能。可以这么做:   再定义一个全局变量flag,判断flag的值,比如 在发送端,先flag++,在pthread_cond_signal; 在接收端while(flag<2)pthread_cond_wait();   这样就ok了。为什么不使用一个全局变量while(flag<2);呢?因为这样很占用CPU,为什么不while(flag<2)usleep(timecnt);呢?   在线程里面sleep函数是不安全的!下篇接受,并解决线程延时问题。    

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/83385.html

(0)
上一篇 2024年 7月 28日
下一篇 2024年 7月 28日

相关推荐

关注微信