download:Python Flask Quick start and advanced
Those of you who have mastered the basic syntax of Python know that the next step is to learn the Python framework, but what framework to choose and how to get through the “lag” period quickly are always difficult problems. We suggest that Flask can be used for transition and initiation. The “light” characteristic of Flask itself makes your learning less “heavy”. After mastering the core knowledge, you will be able to develop and gain a sense of achievement, which will make learning more motivated. FLask’s ability to “quickly” develop various types of applications is very well accepted in the Python Web space
Suitable for people who know the basic syntax of Python but don’t know what to do next students who are new to Python Web development
Basic knowledge of Python syntax and MySQL (basic knowledge of adding, deleting, modifying and checking)
// Acquire acquires the semaphore with a weight of n, blocking until resources // are available or ctx is done. On success, returns nil. On failure, returns // ctx.Err() and leaves the semaphore unchanged. // // If ctx is already done, Acquire may still succeed without blocking. Func (s *Weighted) Acquire(CTX context.context, n int64) error {// There are available resources, Direct victory returns nil s.mailock () if s.size-s.mailiters.Len() == 0 {s.maillock += n.maillock () return nil} // The request resource weight far exceeds the set maximum weight sum, Ctx.err () if n > s.size {// Don’t make other Acquire calls block on one that’s doomed to fail.s.u.nlock () < -ctx.done () return ctx.err ()} Waiters ready: = make(chan struct{}) w := waiter{n: n, waiters := waiters {n: n, waiters := waiters {n: n, waiters := waiters {n: n, waiters: Elem := s.waiters.PushBack(w) s.maillock () select {case < -ctx.done (): Err := ctx.err () s.mlock () select {case <-ready: // Acquired the semaphore after we were canceled. Rather than trying to // fix up the queue, Err = nil default: Err = nil: err = nil: err = nil: err = nil: err = nil: err = nil: err = nil // The control message is received, and the resource has not been obtained. IsFront := s.waiters.Front() == elem // will Remove it from the link above ctx.done () s.waiters.Remove(elem) // If the current element is right at the top of the list and there are available resources, Great waiters > s.collar {s.tifywaiters ()}} s.u.nlock () return err case <-ready: Return nil}} return nil (nil); return nil (nil);
According to available counter information, it can be divided into three conditions:
TryAcquire(), on the other hand, is simply a check on the number of resources available. If there is enough to indicate victory, return true, otherwise false. This method does not stop blocking, but returns directly. // TryAcquire acquires the semaphore with a weight of n without blocking. // On success, returns true. On failure, returns false and leaves the semaphore unchanged. func (s *Weighted) TryAcquire(n int64) bool { s.mu.Lock() success := S.size-s.ur >= n&&s.waiters.Len() == 0 if success {s.ur += n} s.maillock () return success
The release is also simple, as the work stops updating and reducing the number of applied resources (counters) and notifies the rest of them.
// Release releases the semaphore with a weight of n. func (s *Weighted) Release(n int64) { s.mu.Lock() s.cur -= n if S.cour < 0 {s.u.nlock () Panic (” Semaphore: Release more than held”)} s.tifywaiters ()} Loves your work
The for loop iterates all waiters from the head of the list and updates the counter weight. cur and removes them from the list until the number of idle resources is < watier.n.
func (s *Weighted) notifyWaiters() { for { next := s.waiters.Front() if next == nil { break // No more waiters blocked. } w := next.Value.(waiter) if s.size-s.cur < w.n { // Not enough tokens for the next waiter. We could keep going (to try to // find a waiter with a smaller request), but under load that could cause // starvation for large requests; instead, we leave all remaining waiters // blocked. // // Consider a semaphore used as a read-write lock, with N tokens, N // readers, and one writer. Each reader can Acquire(1) to obtain a read // lock. The writer can Acquire(N) to obtain a write lock, excluding all // of the readers. If we allow the readers to jump ahead in the queue, // The writer will starve — there is always one token available for every // reader. break} s.cor += w.n S.waiters.Remove(next) close(w.ready)}} can see if there are more waiters in a linked list, one of the waiters needs more resources (weight) than time, The current Watier blocks for a long time (even if there are enough resources currently available for the other waiter to execute, with some resource waste) until there are enough resources for the wait to execute, and then the wait after it continues to execute.
Using the sample
The official documentation provides a typical form of “working pool” based on semaphores, see pkg.go.dev/golang.org/… Goroutine works concurrently.
This is an example of a semaphore complete and coraz-guessing, stopping the calculation for numbers between 1 and 32 and printing 32 values that fit the result.
package main import ( “context” “fmt” “log” “runtime” “golang.org/x/sync/semaphore” ) // Example_workerPool demonstrates how to use a semaphore to limit the number of // goroutines working on parallel tasks. // // This use of a semaphore Mimics a typical “worker pool” pattern, but without // the need to explicitly shut down idle workers when the work is done. func main() { ctx := context.TODO() Var (maxWorkers = runtime.GOMAXPROCS(0) sem = semaphore.NewWeighted(int64(maxWorkers)) out = make([]int, 32) ) // Compute the output using up to maxWorkers goroutines at a time. for i := range out { // When maxWorkers goroutines are in flight, Acquire blocks until one of the // workers finishes. if err := sem.Acquire(ctx, 1); err ! = nil { log.Printf(“Failed to acquire semaphore: %v”, Err) break} go func(I int) {defer sem.release (1) out[I] = collatzSteps(I + 1)}(I) err := sem.Acquire(ctx, int64(maxWorkers)); err ! = nil { log.Printf(“Failed to acquire semaphore: %v”, err) } fmt.Println(out) } // collatzSteps computes the number of steps to reach 1 under the Collatz // conjecture. (See En.wikipedia.org/wiki/Collat… .). func collatzSteps(n int) (steps int) { if n <= 0 { panic(“nonpositive input”) } for ; n > 1; steps++ { if steps < 0 { panic(“too many