主机屋官网多线程c型 跟多线程t型 有什么区别

浅谈linux 多线程编程和 windows 多线程编程的异同_百度知道
浅谈linux 多线程编程和 windows 多线程编程的异同
提问者采纳
在windows平台下,最终等多久,包括usb驱动,调用它的函数将一直等待到被等待的线程结束为止:注销一个互斥锁。  第四个参数是运行函数的参数,那么整个进行会终止。它们之间的区别是,谈谈windows 和linux usb驱动的东东,第2个线程就做第2步的工作。如果在多线程中采用pthread_cond_wait来等待时,就是条件变量了;   调用这个函数时,不然后果你知道的,pci驱动,在这里不多讲了,第二个参数为一个用户定义的指针,看看他们之间有什么相同点和不同的地方,主要的函数有,就先必须获得互斥量。Msdn一搜。呵呵。因为pthread不是linux系统的库,如果不成功就立即返回。好了,怎样达到最大效率的同步;/&#47,特此对原作者表示感谢;sleep(3):若成功则返回0,但是注意当在这2个函数之间通过return 退出的话:(1) Pthread_cleanup_push?大家讨论有价值的2点如下;=9,且此时返回值为ETIMEDOUT;pthread_create(&t_b。这时,这样需要数据表来维护代码段:这一对函数push和pop的作用是当出现异常退出时;第一个是 创建的互斥对象的句柄,即使当前没有任何线程在等待,linux 和windows是一样的,2个线程同步。restrict 数据类型不改变程序的语义;第一个参数为被等待的线程标识符,在执行前面的函数,那么就是无限等待了;pthread_mutex_unlock(&mutex)有如上两个线程thread_a;&#47,做windows下的应用程序开发,那么b会从pthread_cond_timedwait返回吗,必须注意同步, the function returns back to the caller with an ETIME result。(2)多线程和多进程相比,i=3和i=6时有可能多打印几个, void **__thread_return);}void *thread1(void *junk){for(i=1;&#47,即; &#47:加锁,我用以下表格进行比较。反正我觉得在这种情况下;pthread_mutex_lock函数:  extern int pthread_join __P (pthread_t __th,我们最容易想到的同步方法就是设置一个bool flag了,void *restrict arg),那就首先讲讲吧,然后把这个结构的地址作为arg的参数传入。呵呵,什么时候采用多线程。Linux的条件变量一般都是和互斥锁一起使用的,他们之间传递信息;/do somethingpthread_cond_timedwait(&cond,不是重点:第一种模型是当条件变量置位时(signaled)以后,这种情况就是读脏数据了,如果这个参数为INFINITE。除了采用bool变量外;初始化条件变量void *thread1(void *);count = count + 1,对不同进程来说,是不让数据写入还是让数据覆盖掉老的数据;  返回值,缓冲区迟早会溢出的,它们具有独立的数据空间,当等待的信号到来时;*。呵呵;n&pthread_create(&t_a,我们可以之间共享全局变量,windows下面的的消息机制的函数用的多的就是postmessage了。针对这种情况,再次获得互斥锁;),按理说采用postmessage一个线程就可以搞定这个问题了;Down Mutex&#92:5Up MutexIN oneUp Mutexthread2:对照以上表格,其实当这个程序多执行几次,这个和WaitForSingleObject是不同的,执不执行push后的函数就看pop函数中的参数是不是为0了,现在如果a已经进入了临界区.(2) 2,被等待被下一次唤醒。今天就讲到这里吧,比如最简单的方式就是共享全局变量,如果需要向start_rtn函数传递的参数不止一个,呵呵;pthread_mutex_lock(&mutex);int main(void){pthread_t t_a。在linux下;thead1;/elseprintf(&quot,如果不成功;i&lt:7Up MutexIN onethead1;exit(0):测试加锁,&mutex),仅当第二个指针基于第一个时。新创建的线程从start_rtn函数的地址开始运行;。下面是windows下与互斥的几个函数原型;&#47, &/*创建进程t_a*&#47,只是函数不同罢了:3Down MutexUp MutexIN onethead1,要进行数据的传递只能通过通信的方式进行;可以可用来创建一个有名或无名的互斥量对象第一参数 可以指向一个结构体SECURITY_ATTRIBUTES 一般可以设为null,阻塞等待。你也知道,更好地优化某些类型的例程;pthread_mutex_unlock(&count_lock),这样和多进程相比,等同于在这里面return退出的情况:8Up MutexIN twoIN oneUp Mutexthread2。这个函数是一个线程阻塞的函数,启动新的进程必须分配给它独立的地址空间,不同的线程可以运行不同的cpu下,有些时候采用多线程,所以在编译时注意加上-lpthread参数:4Up MutexIN twoIN onethead1,因此我们只需要掌握好触发的时机即可。第二个是 表示将在多少时间之后返回 如果设为宏INFINITE 则不会返回 直到用户自己定义返回:(1) 线程从启动例程中返回(return)(2) 线程可以被另一个进程终止(kill);int i=1,__in LPCTSTR lpName)。关于pthread_cond_timedwait超时返回的问题:条件变量的置位和复位有2种常用模型,我们可以采用同步技术进行线程之间的通信:6Down MutexIN twothread2。当然使用这些东西都要初始化的。比如说你要做一个任务分2个步骤, const struct timespec *abstime) -- This function is a time-based variant of pthread_cond_pthread_cond_t cond = PTHREAD_COND_INITIALIZER,神马都出来了。临界区的获取和释放函数如下;pthread_mutex_destroy函数。 对于多线程共享内存的东东就讲到这里了,都会执行push里面的清除函数;n&quot,现在想写的是linux下usb驱动和windows下usb驱动开发的区别,其状态会保持为置位(signaled)。但是共享全部变量也要注意哦:(1) pthread_cond_timedwait (pthread_cond_t *n&n&quot:int pthread_join(pthread_t tid,呵呵,才能对对象进行存取;Up Mutex&#92,i),void*(*start_rtn)(void*)。Linux下的消息机制,ndis驱动;(3) 线程自己调用pthread_exit函数#includepthread_exit线程等待,因为你后面的线程在对数据进行操作的时候,(void *)NULL),都会使用waitforsingleobject进行等待的。还有当没有异常退出时.1 pthread_cond_timedwait行为和pthread_cond_wait一样;while (count == 0)pthread_cond_wait(&count_nonzero,会首先释放互斥锁,msdn上 一搜就出来了!=0)pthread_cond_wait(&cond. If abstime elapses before cv is notified,如果谁熟悉的:createmutex 创建一个互斥量;count = count - 1,错误码为EBUSY,先执行后面的那个函数。呵呵。如果是2个线程一直在跑的:2Up MutexIN onethread2,b都在临界区,呵呵,不执行push函数中的清除函数,采用多线程比较理想:初始化一个互斥锁,就转到搞linux开发了,可以采用事件(Event)或信号量(Semaphore)。DWORD WINAPI WaitForSingleObject(__in HANDLE hHandle。thread_a :如果在进程中任何一个线程中调用exit或_pthread_mutex_unlock(&mutex)。就此打住,就不在这里说了,这时主要考虑的就是同步了;*解锁互斥量*&#47。终止线程,以调用静态链接库;}}void *thread2(void *junk){while(i&lt:windows下互斥量的函数有。线程可以被函数pthread_cond_signal和函数 pthread_cond_broadcast唤醒线程被唤醒后;*等待*/),在实际应用中,也就是传说中的加锁了,那岂不是a。临界区和互斥类似;,这样就完全并行了,总结如下。(4)另外要注意的Pthread_cond_timedwait等待的是绝对时间,你可以多线程技术。(2)linux的pthread_cond_signal和SetEvent的不同点Pthread_cond_singal释放信号后,该函数只有一个无指针参数arg。要特别讲讲才行,呵呵,发送信号,我们可以对代码稍加改进就可以避免这种差异的发生,在决定触发条件变量前检查该变量即可;n&quot,这种方法是最容易想到的。如下;&#47。如果pthread_cond_timedwait超时到了。(3)windows下的另外一种线程通信方法就是事件和信号量了,后果很严重的,比如第一个线程完成生产的数据后。由 restrict 修饰的指针是最初唯一对指针所指向的对象进行存取的方法,否则返回出错编号  返回成功时,就出来了。咱们可以多开几个缓冲区进行操作;pthread_mutex_unlock(&count_lock),即当在push和pop函数之间异常退出,Linux系统下的多线程遵循POSIX线程接口。  第二个参数用来设置线程属性;}(3) 注意Pthread_cond_wait条件返回时互斥锁的解锁问题extern int pthread_cond_wait __P ((pthread_cond_t *__cond. Even in the case of timeouts,这里就是竞争锁造成的了,单位是ms:pthread_mutex_lock(&mutex)。  第一个参数为指向线程标识符的指针,超时就返回; &#47,最容易想到的方法就是互斥量了:%d&#92。有时在2个线程所需的时间不相同的时候,一般说来线程应该仍阻塞在这里。其实最开始我是搞windows下编程的。神马都是浮云,当函数返回时;}increment_count(){pthread_mutex_lock(&count_lock); LeaveCriticalSection()离开临界区。pthread_mutex_init函数,包括调用pthread_exit退出。linux下用C开发多线程程序, NULL);thread2。就是用bool变量控制同步,开辟2个线程,这点和SetEvent不同。对于linux,在返回的时候都要再次lock mutex,那么需要把这些参数放到一个结构中;&#47,主要是写linux编程和windows编程的区别吧。在这种情况下。但是你这个时候要注意同步了,或指向由 malloc() 分配的内存空间; &#47,要想进入那段代码,但是这个时候不能lock临界区。条件变量在Linux平台上的这种模型很难说好坏,临界区速度快,__in BOOL bInitialOwner,或Semaphore句柄. It waits up to abstime amount of time for cv to be notified,因此在之后要注意手动解锁;pthread_mutex_lock(&mutex),呵呵,采用事件和信号量同步时候:(1)因为多线程彼此之间采用相同的地址空间。第2个线程就把数据取走,他已经把数据准备好了,呵呵;&#47,比如说在第2个线程还没有用完数据前,thread2。(3)在多cpu的情况下;IN two &#92,信号马上复位了,当条件变量置位(signaled)以后。attr参数用于制定各种不同的线程属性;if(i%3==0)pthread_cond_signal(&cond)。对于windows线程的创建东西,我把它搬过来,互斥也是类似的,其状态才会变为unsignaled,线程解开mutex指向的锁并被条件变量cond阻塞。最简单的做法是增加一个计数器记录等待线程的个数。详解如下,pthread_mutex_t *__mutex))?如果能返回,也是线程同步的方式就是临界区了。既然讲道了这里;*初始化互斥锁*&#47。第2种模型则是Linux平台的pthread所采用的模型:(1)共享全局变量;pthread_cond_t count_nonzero.2 。他们之间可以直接共享数据,SetEvent是不会复位的。因为只有第一步做完才能做第2步的工作,因为多进程的话,当没有Pthread_cond_wait,当pop函数参数为0时,这时候就要具体问题具体分析了:1Up MutexIN twoIN onethead1。采用互斥量进行同步, the external_mutex will be locked when pthread_cond_i++){printf(&quot,并不确切。由于这种差异只会发生在触发没有被线程等待在条件变量的时刻。对对象的存取都限定于基于由 restrict 修饰的指针表达式中。开始将多线程了,让两个线程之间传递数据,省略不讲了,称为pthread?如果不能返回,我用的较少;pthread_mutex_destroy(&mutex),由tidp指向的内存单元被设置为新创建线程的线程ID,然后就是获得互斥量waitforsingleobject函数。函数原型为,共享大部分的数据,被等待线程的资源被收回;IN one&#92,pthread_mutex_unlock,如果还不满足,你不同步保护,注意是是栈:9Down Mutex注意蓝色的地方。就像生产者消费者一样了,这些都是后话,执行清除操作。附录,当第一个线程准备好数据后;pthread_mutex_unlock函数,我也认同观点2。呵呵,第一个线程就做第一步的工作,就直接postmessage给第2个线程。这里就不讲了,NULL,由于时间不一致;decrement_count(){pthread_mutex_lock(&count_lock),大家一起探讨,有2个thread2。(2)采用消息机制进行多线程通信和同步,其实并不是所有的程序都必须采用多线程。HANDLE WINAPI CreateMutex(__in LPSECURITY_ATTRIBUTES lpMutexAttributes:EnterCriticalSection() 进入临界区;printf(&sleep(3),Pthread_cond_timedwait在网上也有讨论,就必须告诉第2个线程,线程正常的退出方式有,pthread_cond_timedwait并不会立即返回;&#47, pthread_mutex_t *external_mutex.2pthread_cond_timedwait所谓的如果没有等到条件变量,呵呵,Pthread_cleanup_pop,上面的问题: int pthread_create(pthread_t *restrict tidp。但是对于多线程就不一样了。举例如下:pthread_mutex_lock(&mutex):pthread_mutex_lock ,共享全局变量同步问题:6Down MutexIN onethead1;do somethingpthread_mutex_unlock(&mutex)thread_b,等我将linux多线程和windows多线程讲解完后。linux上互斥量的函数是,就比较麻烦了;if(i%3;pthread_join(t_b,那pthread_cond_timedwait的定时岂不是就不准了,比如说吧,thread1,而且很不方便;9){printf(&quot,也有类似的方法,当减到0的时候 内核会才会释放其对象,在这里可以是Event句柄,我再写一篇usb驱动,也告诉我:#include#include#includepthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER。在接下来的我还会写一些博客,代价比较节俭,多线程之间通信采用的方法主要有,通知t_b进程*&#47。在这种情况下就要考虑了,google上一搜;pthread_mutex_unlock(&mutex),后面慢慢的我又对linux开发产生比较深的兴趣和爱好,就再讲讲其它同步的方法,1394驱动等等,直到有等待的线程进入被触发:%d\printf(&quot,而b同时超时了,你可以来取走了, thread_b,i), &tm)。 编译器能通过作出 restrict 修饰的指针是存取对象的唯一方法的假设,void **rval_ptr)函数pthread_join用来等待一个线程的结束,怎样把自己知道的东西都写出来,这里windows和linux就有不同了,其状态也会恢复为复位(unsignaled)状态。采用多线程的好处如下:IN onethead1;void *thread2(void *), signifying that a timeout has occurred:6,用完了就释放互斥量ReleaseMutex(hMutex),数据段和堆栈段等等,这种模型以采用Windows平台上的Auto-set Event 为代表,呵呵;pthread_cond_destroy(&cond)。对于););&#47!对于linux操作系统。同样针对我开始举得例子,和互斥相关的几个函数也要闪亮登场了,NULL,做一些清除操作;pthread_t t_b,如果有多个push;释放事件的函数为SetEn"第二参数 指当时的函数是不是感应感应状态 FALSE为当前拥有者不会创建互斥第三参数 指明是否是有名的互斥对象 如果是无名 用null就好,第2个参数就是等待的延迟,如果当前没有线程在等待,一个明显的优点就是线程之间的通信了,第一步要向第2步传递收据,第一个线程不能写入。windows下还有一个可以用来保护数据的方法;*等待进程t_b结束*&#47,性能还没有单线程好,言归正传,但是它只能用来同步同一个进程内的多个线程;*创建进程t_b*&#47,(void *)NULL),它将重新检查判断条件是否满足。  第三个参数是线程运行函数的起始地址。 由 restrict 修饰的指针主要用于函数形参,我们首先讲讲多线程之间的通信。windows下加锁和linux下加锁是类似的;if (count == 0)pthread_cond_signal(&count_nonzero),你第一个线程又改变了数据的内容;pthread_mutex_trylock函数,就不列举了,pthread_cond_initpthread_cond_signalpthread_cond_waitpthread_cond_timewait为了和windows操作系统进行对比,并将它和windows的多线程进行比较;}}输出如下,同时也一条龙服务。所以我们要搞清楚。释放信号量的函数为ReleaseSemaphore(),下面我就谈谈linux多线程及线程同步;至于这些函数的用法。示例 使用 pthread_cond_wait() 和 pthread_cond_signal()pthread_mutex_t count_lock,这里可以采用消息机制。同样 针对上面的这个问题:解锁。对于linux操作系统,它仍在临界区中:这个问题比较经典, &count_lock),它可以用来存储被等待线程的返回值,windows 驱动,你为提高工作效率,但是每当写时又不知道从哪个地方写起,希望是抛砖引玉。部分内容我也是参考internet的,但是在pthread_cond_timedwait返回的时候,这个函数的第一个参数是一个句柄。首先我们讲讲为什么要采用多线程编程,__in DWORD dwMilliseconds),包括windows编程,const pthread_attr_t *restrict_attr很早以前就想写写linux下多线程编程和windows下的多线程编程了;printf(&quot:当pop函数参数不为0时,是采用条件变量来实现类似的功能的,这种方式不仅费时
其他类似问题
为您推荐:
多线程编程的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁10519人阅读
一. 互斥锁
尽管在Posix Thread中同样可以使用IPC的信号量机制来实现互斥锁mutex功能,但显然semphore的功能过于强大了,在Posix Thread中定义了另外一套专门用于线程同步的mutex函数。
1. 创建和销毁
有两种方法创建互斥锁,静态方式和动态方式。POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥锁,方法如下:
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
在LinuxThreads实现中,pthread_mutex_t是一个结构,而PTHREAD_MUTEX_INITIALIZER则是一个结构常量。
动态方式是采用pthread_mutex_init()函数来初始化互斥锁,API定义如下:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
其中mutexattr用于指定互斥锁属性(见下),如果为NULL则使用缺省属性。
pthread_mutex_destroy()用于注销一个互斥锁,API定义如下:
int pthread_mutex_destroy(pthread_mutex_t *mutex)
销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。由于在Linux中,互斥锁并不占用任何资源,因此LinuxThreads中的pthread_mutex_destroy()除了检查锁状态以外(锁定状态则返回EBUSY)没有其他动作。
2. 互斥锁属性
互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。当前(glibc2.2.3,linuxthreads0.9)有四个值可供选择:
PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。
3. 锁操作
锁操作主要包括加锁pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁pthread_mutex_trylock()三个,不论哪种类型的锁,都不可能被两个不同的线程同时得到,而必须等待解锁。对于普通锁和适应锁类型,解锁者可以是同进程内任何线程;而检错锁则必须由加锁者解锁才有效,否则返回EPERM;对于嵌套锁,文档和实现要求必须由加锁者解锁,但实验结果表明并没有这种限制,这个不同目前还没有得到解释。在同一进程中的线程,如果加锁后没有解锁,则任何其他线程都无法再获得锁。
int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_mutex_t *mutex)
int pthread_mutex_trylock(pthread_mutex_t *mutex)
pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待。
POSIX线程锁机制的Linux实现都不是取消点,因此,延迟取消类型的线程不会因收到取消信号而离开加锁等待。值得注意的是,如果线程在加锁后解锁前被取消,锁将永远保持锁定状态,因此如果在关键区段内有取消点存在,或者设置了异步取消类型,则必须在退出回调函数中解锁。
这个锁机制同时也不是异步信号安全的,也就是说,不应该在信号处理过程中使用互斥锁,否则容易造成死锁。
二. 条件变量
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待&条件变量的条件成立&而挂起;另一个线程使&条件成立&(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
1. 创建和注销
条件变量和互斥锁一样,都有静态动态两种创建方式,静态方式使用PTHREAD_COND_INITIALIZER常量,如下:
pthread_cond_t cond=PTHREAD_COND_INITIALIZER
动态方式调用pthread_cond_init()函数,API定义如下:
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
尽管POSIX标准中为条件变量定义了属性,但在LinuxThreads中没有实现,因此cond_attr值通常为NULL,且被忽略。
注销一个条件变量需要调用pthread_cond_destroy(),只有在没有线程在该条件变量上等待的时候才能注销这个条件变量,否则返回EBUSY。因为Linux实现的条件变量没有分配什么资源,所以注销动作只包括检查是否有等待线程。API定义如下:
int pthread_cond_destroy(pthread_cond_t *cond)
2. 等待和激发
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
等待条件有两种方式:无条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间日0时0分0秒。
无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race Condition)。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。
激发条件有两种形式,pthread_cond_signal()激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;而pthread_cond_broadcast()则激活所有等待线程。
pthread_cond_wait()和pthread_cond_timedwait()都被实现为取消点,因此,在该处等待的线程将立即重新运行,在重新锁定mutex后离开pthread_cond_wait(),然后执行取消动作。也就是说如果pthread_cond_wait()被取消,mutex是保持锁定状态的,因而需要定义退出回调函数来为其解锁。
以下示例集中演示了互斥锁和条件变量的结合使用,以及取消对于条件等待动作的影响。在例子中,有两个线程被启动,并等待同一个条件变量,如果不使用退出回调函数(见范例中的注释部分),则tid2将在pthread_mutex_lock()处永久等待。如果使用回调函数,则tid2的条件等待及主线程的条件激发都能正常工作。
#include &stdio.h&
#include &pthread.h&
#include &unistd.h&
pthread_mutex_
pthread_cond_
void * child1(void *arg)
pthread_cleanup_push(pthread_mutex_unlock,&mutex); /* comment 1 */
printf(&thread 1 get running \n&);
printf(&thread 1 pthread_mutex_lock returns %d\n&,
pthread_mutex_lock(&mutex));
pthread_cond_wait(&cond,&mutex);
printf(&thread 1 condition applied\n&);
pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(0); /* comment 2 */
void *child2(void *arg)
sleep(3); /* comment 3 */
printf(&thread 2 get running.\n&);
printf(&thread 2 pthread_mutex_lock returns %d\n&,
pthread_mutex_lock(&mutex));
pthread_cond_wait(&cond,&mutex);
printf(&thread 2 condition applied\n&);
pthread_mutex_unlock(&mutex);
int main(void)
int tid1,tid2;
printf(&hello, condition variable test\n&);
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
pthread_create(&tid1,NULL,child1,NULL);
pthread_create(&tid2,NULL,child2,NULL);
sleep(2); /* comment 4 */
pthread_cancel(tid1); /* comment 5 */
sleep(2); /* comment 6 */
pthread_cond_signal(&cond);
}while(1);
sleep(100);
pthread_exit(0);
如果不做注释5的pthread_cancel()动作,即使没有那些sleep()延时操作,child1和child2都能正常工作。注释3和注释4的延迟使得child1有时间完成取消动作,从而使child2能在child1退出之后进入请求锁操作。如果没有注释1和注释2的回调函数定义,系统将挂起在child2请求锁的地方;而如果同时也不做注释3和注释4的延时,child2能在child1完成取消动作以前得到控制,从而顺利执行申请锁的操作,但却可能挂起在pthread_cond_wait()中,因为其中也有申请mutex的操作。child1函数给出的是标准的条件变量的使用方式:回调函数保护,等待条件前锁定,pthread_cond_wait()返回后解锁。
条件变量机制不是异步信号安全的,也就是说,在信号处理函数中调用pthread_cond_signal()或者pthread_cond_broadcast()很可能引起死锁。
三. 信号灯
信号灯与互斥锁和条件变量的主要不同在于&灯&的概念,灯亮则意味着资源可用,灯灭则意味着不可用。如果说后两中同步方式侧重于&等待&操作,即资源不可用的话,信号灯机制则侧重于点灯,即告知资源可用;没有等待线程的解锁或激发条件都是没有意义的,而没有等待灯亮的线程的点灯操作则有效,且能保持灯亮状态。当然,这样的操作原语也意味着更多的开销。
信号灯的应用除了灯亮/灯灭这种二元灯以外,也可以采用大于1的灯数,以表示资源数大于1,这时可以称之为多元灯。
1. 创建和注销
POSIX信号灯标准定义了有名信号灯和无名信号灯两种,但LinuxThreads的实现仅有无名灯,同时有名灯除了总是可用于多进程之间以外,在使用上与无名灯并没有很大的区别,因此下面仅就无名灯进行讨论。
int sem_init(sem_t *sem, int pshared, unsigned int value)
这是创建信号灯的API,其中value为信号灯的初值,pshared表示是否为多进程共享而不仅仅是用于一个进程。LinuxThreads没有实现多进程共享信号灯,因此所有非0值的pshared输入都将使sem_init()返回-1,且置errno为ENOSYS。初始化好的信号灯由sem变量表征,用于以下点灯、灭灯操作。
int sem_destroy(sem_t * sem)
被注销的信号灯sem要求已没有线程在等待该信号灯,否则返回-1,且置errno为EBUSY。除此之外,LinuxThreads的信号灯注销函数不做其他动作。
2. 点灯和灭灯
int sem_post(sem_t * sem)
点灯操作将信号灯值原子地加1,表示增加一个可访问的资源。
int sem_wait(sem_t * sem)
int sem_trywait(sem_t * sem)
sem_wait()为等待灯亮操作,等待灯亮(信号灯值大于0),然后将信号灯原子地减1,并返回。sem_trywait()为sem_wait()的非阻塞版,如果信号灯计数大于0,则原子地减1并返回0,否则立即返回-1,errno置为EAGAIN。
3. 获取灯值
int sem_getvalue(sem_t * sem, int * sval)
读取sem中的灯计数,存于*sval中,并返回0。
sem_wait()被实现为取消点,而且在支持原子&比较且交换&指令的体系结构上,sem_post()是唯一能用于异步信号处理函数的POSIX异步信号安全的API。
四. 异步信号
由于LinuxThreads是在核外使用核内轻量级进程实现的线程,所以基于内核的异步信号操作对于线程也是有效的。但同时,由于异步信号总是实际发往某个进程,所以无法实现POSIX标准所要求的&信号到达某个进程,然后再由该进程将信号分发到所有没有阻塞该信号的线程中&原语,而是只能影响到其中一个线程。
POSIX异步信号同时也是一个标准C库提供的功能,主要包括信号集管理(sigemptyset()、sigfillset()、sigaddset()、sigdelset()、sigismember()等)、信号处理函数安装(sigaction())、信号阻塞控制(sigprocmask())、被阻塞信号查询(sigpending())、信号等待(sigsuspend())等,它们与发送信号的kill()等函数配合就能实现进程间异步信号功能。LinuxThreads围绕线程封装了sigaction()何raise(),本节集中讨论LinuxThreads中扩展的异步信号函数,包括pthread_sigmask()、pthread_kill()和sigwait()三个函数。毫无疑问,所有POSIX异步信号函数对于线程都是可用的。
int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask)
设置线程的信号屏蔽码,语义与sigprocmask()相同,但对不允许屏蔽的Cancel信号和不允许响应的Restart信号进行了保护。被屏蔽的信号保存在信号队列中,可由sigpending()函数取出。
int pthread_kill(pthread_t thread, int signo)
向thread号线程发送signo信号。实现中在通过thread线程号定位到对应进程号以后使用kill()系统调用完成发送。
int sigwait(const sigset_t *set, int *sig)
挂起线程,等待set中指定的信号之一到达,并将到达的信号存入*sig中。POSIX标准建议在调用sigwait()等待信号以前,进程中所有线程都应屏蔽该信号,以保证仅有sigwait()的调用者获得该信号,因此,对于需要等待同步的异步信号,总是应该在创建任何线程以前调用pthread_sigmask()屏蔽该信号的处理。而且,调用sigwait()期间,原来附接在该信号上的信号处理函数不会被调用。
如果在等待期间接收到Cancel信号,则立即退出等待,也就是说sigwait()被实现为取消点。
五. 其他同步方式
除了上述讨论的同步方式以外,其他很多进程间通信手段对于LinuxThreads也是可用的,比如基于文件系统的IPC(管道、Unix域Socket等)、消息队列(Sys.V或者Posix的)、System V的信号灯等。只有一点需要注意,LinuxThreads在核内是作为共享存储区、共享文件系统属性、共享信号处理、共享文件描述符的独立进程看待的。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:100802次
积分:1155
积分:1155
排名:千里之外
转载:71篇
(1)(1)(2)(3)(5)(9)(14)(12)(1)(10)(8)(9)}

我要回帖

更多关于 主机屋免费空间 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信