Sometimes, Goto is the only choice.

Source: Internet
Author: User

I. Goto plot
Goto, perhaps equivalent to a series of dinosaurs that used to run across the Earth, is just like a dinosaur, and finally becomes extinct. Teacher dijstra was the first to take a picture of Goto and beat the danger of the command. As we can see some code feelings: the person who writes the code is good, and the person who maintains the code is crying. I once caught the tail of the basic language and saw a program written in the early BASIC language. It felt like a roller coaster, and suddenly I ran away.
Later, we became accustomed to discrimination against Goto. Although these statements are often seen in the kernel, they are said to improve efficiency. They are also rational because they are not very understandable after all, it should be okay for people who write code to drop me a few streets, so it is not possible here. However, this is not about efficiency, but about Goto. Although it looks very strange, it is indeed an example in the project, not an example I fabricated.
Ii. pthread_cleanup_push
This is a standard interface in the POSIX thread library, which is used to register a willingness of the thread. If you say that you were unfortunately canceled by pthread_cancel before executing the corresponding pthread_cleanup_pop in the next execution, ask the system to execute the registered callback function for me. Otherwise, inconsistency may occur. After all, after a thread is suspended, other threads may continue to run persistently.
The most typical example here is the mutex lock. When a thread may obtain a lock and start execution, the execution takes a long time and is killed by pthread_cancel during execution, the lock is scrapped. More seriously, it will become a thread black hole. When all threads are executed here, they will be suspended and will never be awakened. For some key operations, the thread registers the unlock callback function for the lock.
Further, an interface may be critical and there should be no flash loss. Therefore, it is not limited by this lock at all, so it can skip the acquiring action of this mutex lock. People may wonder how this happens. After all, this interface may be used to reset the system. If there is a lock exception, the reset operation will fail, this has nothing to do with the interactive system. It is a big deal for everyone to press the power, but it is a tragedy for Embedded Systems (if the watchdog is still working normally ), it will become a zombie system, that is, although running, but functional disorder, and cannot be reset.
To sum up, the model code here is soy sauce:
[Tsecer @ Harry gotoonly] $ cat gotoonly. c
# Include <pthread. h>
Int dosomething (INT lockfree)
{
Static pthread_mutex_t locker = pthread_mutex_initializer;
/* Here we will get the lock */
If (! Lockfree)
{
Pthread_cleanup_push (void (*) (void *) pthread_mutex_unlock, (void *) & locker );
Pthread_mutex_lock (& locker );
}
/* Here may do a lot of stuff */
{
Extern void Foo (void );
}
/* Here starts the cleanup */
If (! Lockfree)
{
Pthread_cleanup_pop (1 );
}
}
The logic of the code is to execute the pthread_cleanup_push/pthread_cleanup_pop operation in some cases, but it is not executed afterwards. Therefore, put them in an if condition, but this Code cannot be compiled.
Iii. Compilation Error
When compiling this Code, some errors are prompted because no while operation is used in the code.
[Tsecer @ Harry gotoonly] $ GCC gotoonly. C-C
Gotoonly. C: In function 'dosomething ':
Gotoonly. C: 12: Error: Expected 'while 'before' _ init'
So this must be a problem after preprocessing. Let's take a look at the preprocessing results.
[Tsecer @ Harry gotoonly] $ tail-N 20 gotoonly. c. I
#2 "gotoonly. c" 2
Int dosomething (INT lockfree)
{
Static pthread_mutex_t locker = {0, 0, 0, 0, 0, {0 }}};
/* Here we will get the lock */
If (! Lockfree)
{Note: The left parenthesis here matches the right parenthesis of the same color below.

Do {_ pthread_unwind_buf_t _ cancel_buf; void (* _ cancel_routine) (void *) = (void (*) (void *) pthread_mutex_unlock ); void * _ cancel_arg = (void *) & locker); int not_first_call = _ sigsetjmp (struct _ jmp_buf_tag
*) (Void *) _ cancel_buf. _ blank, 0); If (_ builtin_exact CT (not_first_call, 0) {_ cancel_routine (_ cancel_arg); _ pthread_unwind_next (& __ cancel_buf );} _ pthread_register_cancel (& __ cancel_buf );

Do {;

Pthread_mutex_lock (& locker );
}
/* Here may do a lot of stuff */
{
Extern void Foo (void );
}
/* Here starts the cleanup */
If (! Lockfree)
{
Do {} while (0);} while (0); _ pthread_unregister_cancel (& __ cancel_buf); if (1) _ cancel_routine (_ cancel_arg );} while (0 );
}
}
We can see that this is completely out of order, so the compilation is just the best. If there is no error and the executable file is compiled, it will be more complicated to locate the problem.
Iv. Man manual description of the Function
Posix.1 permits pthread_cleanup_push () and pthread_cleanup_pop () to be
Implemented as macros that expand to text ining '{' and '}',
Respectively. For this reason,The caller must ensure that callto
These functions are supported Red within the same function, and at the same
Lexical nesting level
. (In other words, a clean-up handler is only
Established during the execution of a specified section of code .)

Pthread_cleanup_pop and pthread_cleanup_push must be in the same function and in the same lexical domain. This is a strong constraint, so the above Code has syntax errors, and glibc does implement these two functions as macros.
V. Goto debut
Code after modification
[Tsecer @ Harry gotoonly] $ cat gotoonlygoto. c
# Include <pthread. h>
Int dosomething (INT lockfree)
{
Static pthread_mutex_t locker = pthread_mutex_initializer;
/* Here we will get the lock */
If (lockfree)
Goto lockskipped;
Pthread_cleanup_push (void (*) (void *) pthread_mutex_unlock, (void *) & locker );
Pthread_mutex_lock (& locker );
Lockskipped:
/* Here may do a lot of stuff */
{
Extern void Foo (void );
}
/* Here starts the cleanup */
If (lockfree)
Goto unlockskipped;
Pthread_cleanup_pop (1 );
Unlockskipped:
0;
}
[Tsecer @ Harry gotoonly] $ GCC gotoonlygoto. C-C
[Tsecer @ Harry gotoonly] $

As the saying goes: Goto, the weapon is also used as a last resort.


From: http://tsecer.blog.163.com/blog/static/1501817201221882145262/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.