Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 4

0
votes
answers
70 views
+10

gitlab通過golang抓取的問題

1

我是編程新手,我需要幫助。試圖在golang上編寫gitlab scraper。 當我試圖在多線程模式下獲取有關項目的信息時,出現了一些問題。gitlab通過golang抓取的問題

下面是代碼:

func (g *Gitlab) getAPIResponce(url string, structure interface{}) error { 
    responce, responce_error := http.Get(url) 
    if responce_error != nil { 
     return responce_error 
    } 
    ret, _ := ioutil.ReadAll(responce.Body) 
    if string(ret) != "[]" { 
     err := json.Unmarshal(ret, structure) 
     return err 
    } 
    return errors.New(error_emptypage) 
} 

... 

func (g *Gitlab) GetProjects() { 
    projects_chan := make(chan Project, g.LatestProjectID) 
    var waitGroup sync.WaitGroup       
    queue := make(chan struct{}, 50)          
    for i := g.LatestProjectID; i > 0; i-- {    
     url := g.BaseURL + projects_url + "/" + strconv.Itoa(i) + g.Token 
     waitGroup.Add(1) 
     go func(url string, channel chan Project) { 
      queue <- struct{}{} 
      defer waitGroup.Done() 

      var oneProject Project 
      err := g.getAPIResponce(url, &oneProject) 
      if err != nil { 
       fmt.Println(err.Error()) 
      } 

      fmt.Printf(".") 
      channel <- oneProject 
      <-queue 
     }(url, projects_chan) 
    } 

    go func() { 
     waitGroup.Wait() 
     close(projects_chan) 
    }() 

    for project := range projects_chan { 
     if project.ID != 0 { 
      g.Projects = append(g.Projects, project) 
     } 
    } 
} 

這裏是輸出:

┌[ nb-kondrashov: ~/Gitlab/gitlab-auditor ] 
└[ skondrashov ]-> ./gitlab-auditor 
latest project = 1532 
Gathering projects... 
.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................Get https://gitlab.example.com/api/v4/projects/563&private_token=SeCrEt_ToKeN: unexpected EOF 
Get https://gitlab.example.com/api/v4/projects/558&private_token=SeCrEt_ToKeN: unexpected EOF 
..Get https://gitlab.example.com/api/v4/projects/531&private_token=SeCrEt_ToKeN: unexpected EOF 
Get https://gitlab.example.com/api/v4/projects/571&private_token=SeCrEt_ToKeN: unexpected EOF 
.Get https://gitlab.example.com/api/v4/projects/570&private_token=SeCrEt_ToKeN: unexpected EOF 
..Get https://gitlab.example.com/api/v4/projects/467&private_token=SeCrEt_ToKeN: unexpected EOF 
Get https://gitlab.example.com/api/v4/projects/573&private_token=SeCrEt_ToKeN: unexpected EOF 
................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ 

每當它的不同的項目,但它的id是大約550

當我試圖從輸出中扼制鏈接,我得到正常的JSON。當我試圖用queue := make(chan struct{}, 1)(單線程)運行這段代碼時 - 一切都很好。

它可能是什麼?

+2

嘗試限制同時連接的數量。 –

+0

我想在這裏做:'queue:= make(chan struct {},N)'(N =連接數),並且它有部分幫助,但是我失去了性能。這是gitlab,golang或我的電腦的問題嗎? – sergkondr

+1

我想50是太多了。可能存在某種限制連接數量的DDoS保護。嘗試減少,例如5或10. –

沙发
0
1

我會說這不是一個非常明確的方法來實現併發。 whhat似乎是這裏發生的是

  • 您創建的大小爲50

  • 緩衝通道,那麼你火了1532個夠程

  • 他們的第一個50本身排隊並開始處理。當他們< - 排隊並釋放一些空間時,下一個隨機的一個管理員進入隊列。

  • 正如人們在評論中所說的那樣,當然你在某些限制的範圍內遇到了一些限制,比如說550 gitlab的API對你感到憤怒並且限制了速度。

  • 然後另一個夠程進行燒製,將關閉通道通知主夠程

  • 主夠程讀取消息。

談話go concurrency patterns 以及這個博客帖子concurrency in go可能的幫助。 我個人很少使用緩衝頻道。你的問題,我會是這樣的:

  • 定義多個工人

  • 有主夠程火了一個FUNC聽INTS的通道上,這樣做的API調用,寫工人一個項目的渠道

  • 有主要的goroutine發送到一個項目編號的渠道,從項目的渠道中讀取和讀取。

    • 也許ratelimit通過發射一個代碼,並有主讀取之前它發送下一個請求?
  • 主要關閉號碼通道以通知其他人死亡。

+0

感謝您的回答,特別感謝鏈接到「去併發模式」。我已經通過限制線程數量並根據Eugene Lisitsky的回答調整Gitlab來解決了這個問題 – sergkondr

0
votes
answers
50 views
+10

cv2適用於線程,但不適用於進程

1

大家好,感謝您的幫助。 我有這個功能來保存我的攝像頭拍攝的視頻的視頻。cv2適用於線程,但不適用於進程

import cv2 
import multiprocessing 
import threading 
def rec(): 
    # Define the codec and create VideoWriter object 
    fourcc = cv2.VideoWriter_fourcc(*'XVID') 
    out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480)) 

    while(cap.isOpened()): 
     ret, frame = cap.read() 
     if ret==True: 
      out.write(frame) 
     else: 
      break 

    # Release everything if job is finished 
    cap.release() 
    out.release() 
    cv2.destroyAllWindows() 

如果我用它來與線程,所以用這個代碼,它工作得很好:

s1 = threading.Thread(target=rec) 
s1.start() 

但是如果我要開始另一個進程,使用下面的代碼,當我打開視頻它只包含有一些噪音的黑色框架。

s1 = multiprocessing.Process(target=rec) 
s1.start() 

我搜索了四周,但找不到任何解決方案。

另外,我使用Python 3.6

+1

你真的想用多個進程寫入同一個文件,還是我看錯了你的問題? – PeterT

+0

你讀錯了:)我想要一個主處理記錄,而主處理其他事情的子處理 – Weizen

+0

我應該使用子進程而不是多處理? – Weizen

沙发
0
1

cap定義在哪裏?嘗試在你給多處理的函數中定義它。如果它在父級中定義並從父級傳遞給子級,則會被醃製,並且可能會導致它無法使用。

+0

即使我在函數內部定義它也不工作。 – Weizen

板凳
0
1

我解決了這個問題。 我在我的主要和我的一個導入模塊中調用cap = cv2.VideoCapture(0),並且發生衝突。我通過調用一次就解決了。

0
votes
answers
34 views
+10

java中的線程 - 使用內部運行睡眠

-1

我想在打印過程後停止註冊的秒數,但是當我運行播放功能時,它不會進入睡眠狀態。 我可以讓播放功能睡眠,但我想直接在運行功能中運行thread.sleep()。這是可能的嗎?我該如何做到這一點?java中的線程 - 使用內部運行睡眠

我有以下代碼:

public class Player implements Runnable { 
    private String name; 
    private String MusicalInstrument; 
    Player(String name, String MusicalInstrument) { 
     this.name = name; 
     this.MusicalInstrument = MusicalInstrument; 
    } 
    public void run() { 
     try { 
      play(); 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 


    public void play() { 
     while (true) { 
      // print a message 
      System.out.println(name + " is playing " + MusicalInstrument); 
     } 
    } 
} 
+1

所以你有一個無限循環,不明白爲什麼它是無限的? –

+1

這個問題不是'睡眠',而是'while(true)' –

+0

作爲一個挑剔的玩家,'MusicalInstrument'應該是'musicalInstrument',因爲它不是一個類名。 –

沙发
0
5

你只是不斷地去打印,因爲你而()將無限期運行,您的播放方法裏面,所以你永遠不會返回併到達內部的Thread.sleep方法調用你的run()方法。你應該重新修改你的方法,使其更適合你所要做的事情。

public void run() { 
    while(true) 
    { 
     try { 
      play(); 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 


public void play() { 
    System.out.println(name + " is playing " + MusicalInstrument); 
} 
+0

我假定您的意思是「您永遠不會達到sleep()方法」... – Gray

0
votes
answers
38 views
+10

讓兩個對象同時旋轉

0

所以我有這個任務,我必須讓兩個對象同時移動。我知道我應該使用線程類,但我不知道如何去做。我的項目有兩個文件。第一個主要方法和實現風扇object.Here它是:讓兩個對象同時旋轉

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import java.awt.Graphics; 


    public class DrawArcs extends JFrame { 
    public DrawArcs() { 
     setTitle("DrawArcs"); 
     add(new ArcsPanel()); 
    } 

    /** Main method */ 
    public static void main(String[] args) { 
     DrawArcs frame = new DrawArcs(); 
     frame.setLocationRelativeTo(null); // Center the frame 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(300, 300); 
     frame.setVisible(true); 
     frame.add(new StillClock()); 


    } 
    } 

    class ArcsPanel extends JPanel { 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     int xCenter = getWidth()/2; 
     int yCenter = getHeight()/2; 
     int radius = (int)(Math.min(getWidth(), getHeight()) * 0.4); 

     int x = xCenter - radius; 
     int y = yCenter - radius; 

     g.fillArc(x, y, 2 * radius, 2 * radius, 0, 30); 
     g.fillArc(x, y, 2 * radius, 2 * radius, 90, 30); 
     g.fillArc(x, y, 2 * radius, 2 * radius, 180, 30); 
     g.fillArc(x, y, 2 * radius, 2 * radius, 270, 30); 
    } 
} 

我的第二個文件包括實施的時鐘類。

public class StillClock extends JPanel { 
    private int hour; 
    private int minute; 
    private int second; 


    public StillClock() { 
     setCurrentTime(); 
    } 


    public StillClock(int hour, int minute, int second) { 
     this.hour = hour; 
     this.minute = minute; 
     this.second = second; 
    } 
////there are setters and getters here 
. 
. 
. 
//// 

    @Override /** Draw the clock */ 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     // Initialize clock parameters 
     int clockRadius = 
       (int)(Math.min(getWidth(), getHeight()) * 0.8 * 0.5); 
     int xCenter = getWidth()/2; 
     int yCenter = getHeight()/2; 

     // Draw circle 
     g.setColor(Color.black); 
     g.drawOval(xCenter - clockRadius, yCenter - clockRadius, 
       2 * clockRadius, 2 * clockRadius); 
     g.drawString("12", xCenter - 5, yCenter - clockRadius + 12); 
     g.drawString("9", xCenter - clockRadius + 3, yCenter + 5); 
     g.drawString("3", xCenter + clockRadius - 10, yCenter + 3); 
     g.drawString("6", xCenter - 3, yCenter + clockRadius - 3); 

     // Draw second hand 
     int sLength = (int)(clockRadius * 0.8); 
     int xSecond = (int)(xCenter + sLength * 
       Math.sin(second * (2 * Math.PI/60))); 
     int ySecond = (int)(yCenter - sLength * 
       Math.cos(second * (2 * Math.PI/60))); 
     g.setColor(Color.red); 
     g.drawLine(xCenter, yCenter, xSecond, ySecond); 

     // Draw minute hand 
     int mLength = (int)(clockRadius * 0.65); 
     int xMinute = (int)(xCenter + mLength * 
       Math.sin(minute * (2 * Math.PI/60))); 
     int yMinute = (int)(yCenter - mLength * 
       Math.cos(minute * (2 * Math.PI/60))); 
     g.setColor(Color.blue); 
     g.drawLine(xCenter, yCenter, xMinute, yMinute); 

     // Draw hour hand 
     int hLength = (int)(clockRadius * 0.5); 
     int xHour = (int)(xCenter + hLength * 
       Math.sin((hour % 12 + minute/60.0) * (2 * Math.PI/12))); 
     int yHour = (int)(yCenter - hLength * 
       Math.cos((hour % 12 + minute/60.0) * (2 * Math.PI/12))); 
     g.setColor(Color.green); 
     g.drawLine(xCenter, yCenter, xHour, yHour); 
    } 

    public void setCurrentTime() { 
     // Construct a calendar for the current date and time 
     Calendar calendar = new GregorianCalendar(); 

     // Set current hour, minute and second 
     this.hour = calendar.get(Calendar.HOUR_OF_DAY); 
     this.minute = calendar.get(Calendar.MINUTE); 
     this.second = calendar.get(Calendar.SECOND); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(200, 200); 
    } 
} 

所以我的問題是如何讓風扇和時鐘同時旋轉?

這裏是如何看起來運行代碼enter image description here

+0

開始由具有看看搖擺定時器來更新你根據 – MadProgrammer

+0

什麼是你想旋轉的狀態,發生了什麼,爲什麼這是不正確的,應該怎樣HAP鋼筆? – vandale

+0

@vandale我想旋轉時鐘和風扇板的腿 – Marina

沙发
0
1

所以,你實際上問兩個問題:

  1. 如何動畫對象的數量
  2. 如何旋轉對象(作爲時鐘不需要旋轉)

旋轉

2D圖形中的旋轉相對簡單,並提供了多種可能的選項。我打算使用AffineTransform作爲個人偏好。

我們需要幾件事情添加到ArcsPanel,我們需要一個angle,它代表旋轉的當前角度,和delta,其代表着每個動畫運動通過量...

public static class ArcsPanel extends JPanel { 

    protected static final float DELTA = 1.0f; 
    private float angle = 0; 

有了這些信息,我們可以簡單地修改paintComponent方法來支持angle性能和應用AffineTransform

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 

    Graphics2D g2d = (Graphics2D) g.create(); 

    int xCenter = getWidth()/2; 
    int yCenter = getHeight()/2; 
    int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4); 

    g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(angle), xCenter, yCenter)); 

    int x = xCenter - radius; 
    int y = yCenter - radius; 

    g2d.fillArc(x, y, 2 * radius, 2 * radius, 0, 30); 
    g2d.fillArc(x, y, 2 * radius, 2 * radius, 90, 30); 
    g2d.fillArc(x, y, 2 * radius, 2 * radius, 180, 30); 
    g2d.fillArc(x, y, 2 * radius, 2 * radius, 270, 30); 
    g2d.dispose(); 
} 

Animati ng許多對象

儘管您可能會想,但您不需要更多線程,實際上您只需要一個線程。這一個線程將通知所有你想更新的對象,他們應該更新他們的動畫狀態。這個線程並不關心他們如何做到這一點,它只會推動這個過程。同樣,你的物體並不關心發動機是如何工作的,只是它會定期通知他們。

現在,Swing既是單線程的,也不是線程安全的。這在處理線程時引發了一些問題。您不能在Event Dispatching Thread的上下文中運行長時間運行或阻塞操作,也不應該從EDT外部更新UI的狀態。

爲了簡單起見,Swing Timer是一個完美的選擇,因爲它等待EDT,但觸發它在EDT中的更新。

首先,我們需要一些方法讓引擎告訴其他對象他們應該更新自己。當然,您可以簡單地維護對其他組件的直接引用,但這既增加了對象之間的耦合,也限制了引擎的可重用性。

相反,我們定義了一個簡單的接口...

public interface Animatable { 
    public void updateAnimatedState(); 
} 

希望得到通知的所有對象均實現這個interface,可以與發動機

public class Engine { 

    private List<Animatable> animatables; 
    private Timer timer; 

    public Engine() { 
     animatables = new ArrayList<>(4); 
     timer = new Timer(10, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Animatable animatable : animatables) { 
        animatable.updateAnimatedState(); 
       } 
      } 
     }); 
    } 

    public void add(Animatable animatable) { 
     animatables.add(animatable); 
    } 

    public void start() { 
     timer.start(); 
    } 

    public void stop() { 
     timer.stop(); 
    } 
} 

現在註冊,我們需要做的是更新的兩種成分...

public static class ArcsPanel extends JPanel implements Animatable { 
    //... 
    @Override 
    public void updateAnimatedState() { 
     angle += DELTA; 
     repaint(); 
    } 
} 

public class StillClock extends JPanel implements Animatable { 
    //... 

    @Override 
    public void updateAnimatedState() { 
     setCurrentTime(); 
     repaint(); 
    } 
} 

您會注意到我已經稍微修改了您的代碼,以便兩個組件現在都從JPanel延伸,從JFrame延伸的極其有限克,一般不鼓勵。

最後,我們只需要設置這一切......

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       ArcsPanel arcPanel = new ArcsPanel(); 
       StillClock clockPanel = new StillClock(); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new GridLayout(0, 2)); 
       frame.add(arcPanel); 
       frame.add(clockPanel); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       Engine engine = new Engine(); 
       engine.add(arcPanel); 
       engine.add(clockPanel); 
       engine.start(); 
      } 
     }); 
    } 
} 

Runnable的例子...

而且因爲我知道如何混亂的一堆亂背景下的代碼片段可以是...

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.AffineTransform; 
import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.GregorianCalendar; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       ArcsPanel arcPanel = new ArcsPanel(); 
       StillClock clockPanel = new StillClock(); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new GridLayout(0, 2)); 
       frame.add(arcPanel); 
       frame.add(clockPanel); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       Engine engine = new Engine(); 
       engine.add(arcPanel); 
       engine.add(clockPanel); 
       engine.start(); 
      } 
     }); 
    } 

    public class Engine { 

     private List<Animatable> animatables; 
     private Timer timer; 

     public Engine() { 
      animatables = new ArrayList<>(4); 
      timer = new Timer(10, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        for (Animatable animatable : animatables) { 
         animatable.updateAnimatedState(); 
        } 
       } 
      }); 
     } 

     public void add(Animatable animatable) { 
      animatables.add(animatable); 
     } 

     public void start() { 
      timer.start(); 
     } 

     public void stop() { 
      timer.stop(); 
     } 
    } 

    public interface Animatable { 

     public void updateAnimatedState(); 
    } 

    public static class ArcsPanel extends JPanel implements Animatable { 

     protected static final float DELTA = 1.0f; 
     private float angle = 0; 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(300, 300); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      Graphics2D g2d = (Graphics2D) g.create(); 

      int xCenter = getWidth()/2; 
      int yCenter = getHeight()/2; 
      int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4); 

      g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(angle), xCenter, yCenter)); 

      int x = xCenter - radius; 
      int y = yCenter - radius; 

      g2d.fillArc(x, y, 2 * radius, 2 * radius, 0, 30); 
      g2d.fillArc(x, y, 2 * radius, 2 * radius, 90, 30); 
      g2d.fillArc(x, y, 2 * radius, 2 * radius, 180, 30); 
      g2d.fillArc(x, y, 2 * radius, 2 * radius, 270, 30); 
      g2d.dispose(); 
     } 

     @Override 
     public void updateAnimatedState() { 
      angle += DELTA; 
      repaint(); 
     } 
    } 

    public class StillClock extends JPanel implements Animatable { 

     private int hour; 
     private int minute; 
     private int second; 

     public StillClock() { 
      setCurrentTime(); 
     } 

     public StillClock(int hour, int minute, int second) { 
      this.hour = hour; 
      this.minute = minute; 
      this.second = second; 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(300, 300); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      // Initialize clock parameters 
      int clockRadius 
          = (int) (Math.min(getWidth(), getHeight()) * 0.8 * 0.5); 
      int xCenter = getWidth()/2; 
      int yCenter = getHeight()/2; 

      // Draw circle 
      g.setColor(Color.black); 
      g.drawOval(xCenter - clockRadius, yCenter - clockRadius, 
          2 * clockRadius, 2 * clockRadius); 
      g.drawString("12", xCenter - 5, yCenter - clockRadius + 12); 
      g.drawString("9", xCenter - clockRadius + 3, yCenter + 5); 
      g.drawString("3", xCenter + clockRadius - 10, yCenter + 3); 
      g.drawString("6", xCenter - 3, yCenter + clockRadius - 3); 

      // Draw second hand 
      int sLength = (int) (clockRadius * 0.8); 
      int xSecond = (int) (xCenter + sLength 
          * Math.sin(second * (2 * Math.PI/60))); 
      int ySecond = (int) (yCenter - sLength 
          * Math.cos(second * (2 * Math.PI/60))); 
      g.setColor(Color.red); 
      g.drawLine(xCenter, yCenter, xSecond, ySecond); 

      // Draw minute hand 
      int mLength = (int) (clockRadius * 0.65); 
      int xMinute = (int) (xCenter + mLength 
          * Math.sin(minute * (2 * Math.PI/60))); 
      int yMinute = (int) (yCenter - mLength 
          * Math.cos(minute * (2 * Math.PI/60))); 
      g.setColor(Color.blue); 
      g.drawLine(xCenter, yCenter, xMinute, yMinute); 

      // Draw hour hand 
      int hLength = (int) (clockRadius * 0.5); 
      int xHour = (int) (xCenter + hLength 
          * Math.sin((hour % 12 + minute/60.0) * (2 * Math.PI/12))); 
      int yHour = (int) (yCenter - hLength 
          * Math.cos((hour % 12 + minute/60.0) * (2 * Math.PI/12))); 
      g.setColor(Color.green); 
      g.drawLine(xCenter, yCenter, xHour, yHour); 
     } 

     public void setCurrentTime() { 
      // Construct a calendar for the current date and time 
      Calendar calendar = new GregorianCalendar(); 

      // Set current hour, minute and second 
      this.hour = calendar.get(Calendar.HOUR_OF_DAY); 
      this.minute = calendar.get(Calendar.MINUTE); 
      this.second = calendar.get(Calendar.SECOND); 
     } 

     @Override 
     public void updateAnimatedState() { 
      setCurrentTime(); 
      repaint(); 
     } 
    } 
} 
+0

當我嘗試運行您的Runnable示例時出現錯誤:無法找到或加載主類DrawArcs。我不知道如何解決它,雖然我的文件名是DrawArcs.java,所以它可能與此有關。 – Marina

+0

我的示例中沒有'DrawArcs'類 – MadProgrammer

+0

是的,我通過將Test class更改爲DrawArcs類來修復它。謝謝您的回答! – Marina

0
votes
answers
22 views
+10

如何正確執行多線程以便各個線程上的圖標一起移動到屏幕上?

1

我試圖創建一個動畫,其中給定數量的圖標從框架的左側開始並移動到屏幕的右側。圖標垂直排列,每個圖標應該在自己的線程上運行。如何正確執行多線程以便各個線程上的圖標一起移動到屏幕上?

如何獲取所有圖標來做到這一點?當我創建每個賽車手時,我嘗試調整posY,但到目前爲止,我只能獲得創建的最後一名賽車手來顯示。

import javax.swing.*; 
import java.awt.*; 

public class Races { 
    private JFrame frame; 
    private JPanel gui; 
    private Icon img; 
    private int imgWidth; 
    private int imgHeight; 
    private int numOfRacers; // num of threads/racers 

    public static void main(String[] args) { 
     new Races(5); 
    } 

    public Races(int num) { 
     numOfRacers = num; 
     createGUI(); 
     frame.add(gui); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private void createGUI() { 
     frame = new JFrame("Off to the Races - by Brienna Herold"); 
     gui = new JPanel(); 
     gui.setPreferredSize(new Dimension(imgWidth * 20, imgHeight * numOfRacers)); 

     img = new ImageIcon("races.png"); 
     imgWidth = img.getIconWidth(); 
     imgHeight = img.getIconHeight(); 

     int posY = 0; 
     for (int i = 0; i < numOfRacers; i++) { 
      System.out.println("Starting new thread..." + posY); 
      racer = new Racer(posY); 
      Thread racerThread = new Thread(racer); 
      racerThread.start(); 
      posY += imgHeight; 
     } 
    } 

    protected class Racer extends JPanel implements Runnable { 
     private int lastPosX; 
     private int posX; 
     private int posY; 

     public Racer(int _posY) { 
      posX = 0; 
      posY = _posY; 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      // Call the method on the JPanel 
      super.paintComponent(g); 
      img.paintIcon(gui, g, posX, posY); 
      //posY += imgHeight; 
      posX += lastPosX + 3; 
     } 

     @Override 
     public void run() { 
      while (true) { 
       repaint(); 
       try { 
        Thread.sleep(100); 
       } catch (InterruptedException ex) { 
        ex.printStackTrace(); 
       } 
      } 
     } 
    } 

} 
沙发
0
0
gui.add(racer, BorderLayout.CENTER); 

你永遠只能添加一個賽車部件的框架。

但到目前爲止,我只能得到創建的最後一個賽車手來顯示。

「racer」變量指向創建的最後一個Racer組件。

如果您需要多個組件,那麼您將需要使用空佈局創建一個面板。然後,您需要將每個Racer組件添加到此面板,然後將面板添加到框架。使用這種方法,您將通過使用組件的setLocation(...)方法來移動組件。

如果您想在不同位置繪製圖像,那麼您將使用一個包含ArrayList或Racer對象的面板。然後,當面板的paintComponent()方法被調用時,您遍歷List並在每個Racer的新位置繪製。

+0

哦。讓我試試這個。 – briennakh

+0

不是你不只是繪畫。除非將組件添加到框架,否則無法繪製組件。 – camickr

+0

我現在明白了。我要去研究它。 – briennakh

0
votes
answers
18 views
+10

猜測數字在時間限制內

-1

我一直在練習線程,所以我寫了這個定時遊戲,用戶需要猜測正確的數字(範圍從1-10)。如果用戶在時間限制內猜到了正確答案,則線程停止並且程序終止。當用戶在時間限制內未能猜出時,它無法工作。即使它在時間限制之後進入if語句,它仍然不能完全中斷該線程,除非我猜想正確的數字。我已閱讀其他線程,但他們似乎使用詢問有關「傳統」猜謎遊戲或利用Timer。對於建議的解決方案的解釋和/或提示也被讚賞。猜測數字在時間限制內

import java.util.*; 
    import static java.lang.System.out; 
    import java.io.*; 

    public class Threading implements Runnable { 
     private static int num; 
     private static int k; 

    public void run() { 
     try { 
      Scanner line = new Scanner(System.in); 
      k = -1; 
      out.println("Guess!"); 
      while (k != num) { 
       k = line.nextInt(); 
       if (k != num) { 
        out.println("Nope"); 
       } 
      } 

     } 
     catch (Exception e) { 
      out.println("I'm not done!"); 
     } 
    } 

    public static void main(String args[]) throws InterruptedException { 

     num = (int) (Math.random() * 9 + 1); 
     out.println(num); 
     Thread t = new Thread(new Threading()); 
     t.start(); 

     long patience = 1000 * 5; 
     long startTime = System.currentTimeMillis(); 
     while (t.isAlive()) { 
      t.join(1000); 
      if (((System.currentTimeMillis() - startTime) > patience) && t.isAlive()) { 
       out.println("I'm in here!"); 
       t.interrupt(); 
       t.join(); 
       out.println("Times up!"); 
      } 
     } 
    } 
} 
+1

[如何中斷java.util.Scanner nextLine調用](https://stackoverflow.com/questions/4983065/how-to-interrupt-java-util-scanner-nextline-call) –

+0

@MarkMucha是否有必要使用Streams/Buffers來使代碼正常工作?有沒有辦法結束'nextInt()'的「block」? – TypeHereToSearch

沙发
0
0

由於一個評論已經指出,在調用nextInt會阻止我不認爲有必要進入箇中詳情。

所以現在我會假設你很好,允許用戶1在計時器到期後進行最後的猜測。

以下是修改的代碼,包括我的評論。我把你稱爲t的線程稱爲「猜測線程」。現在

private static int num; 
private static int k; 
//Changed variable "line" to "scanner" and made it static so that the 
// main method can close it once everything is done. 
private static Scanner scanner = new Scanner(System.in); 

public void run() { 
    try { 
     k = -1; 
     System.out.println("Guess!"); 
     while (k!=num) { 
      //Added a check for interrupt, otherwise this thread will never 
      // end unless the user enters the correct answer. 
      if(Thread.currentThread().isInterrupted()) 
       return; 
      k = scanner.nextInt(); 
      if(k != num){ 
       System.out.println("Nope"); 
      } 
     } 
     System.out.println("Correct!"); 

    } catch (Exception e) { 
     System.out.println("I'm not done!"); 
    } 
} 

public static void main(String args[]) throws InterruptedException { 

    num = (int) (Math.random() * 9 + 1); 
    System.out.println(num); 
    //Declared the guessing thread as final so it can be used inside of 
    // the TimerTask that is created later. 
    final Thread t = new Thread(new GuessUntilTimeLimit()); 
    t.start(); 

    long patience = 1000 * 5; 

    //Use a Timer to enforce your time limit, the TimerTask will execute 
    // an interrupt of your guessing thread if the thread is still alive 
    // (it may have died already if user got right answer) 
    Timer timer = new Timer(); 
    TimerTask task = new TimerTask(){ 

     @Override 
     public void run() { 
      if(t.isAlive()){ 
       t.interrupt(); 
       System.out.println("Times up! Enter your final guess now."); 
      }    
     } 
    }; 
    timer.schedule(task, patience); 
    //Wait for the guessing thread to finish before canceling the timer 
    t.join(); 
    //By now either the user got the answer or time has run out. Either way 
    // we need to clean up by canceling the timer. 
    timer.cancel(); 
    //Added a call to close the scanner, it's always important to release 
    // resources 
    scanner.close(); 
} 

你的主線程schedules a taskpatience毫秒執行。然後該任務負責interrupting「猜測線程」。 「猜測線程」將檢查interrupt並在適當時自行停止。

同樣,根據您的要求,您可能需要更改接受用戶輸入的方式,因爲nextInt會阻止該線程。爲了完整起見,我在鏈接中提到了評論中提到的question regarding interrupting Scanner.nextLine

0
votes
answers
17 views
+10

在Python 2.7中立即停止線程執行/終止

0

我正在設計一個基於QT的應用程序,它是用Python設計的。該應用程序具有以下兩個按鈕:在Python 2.7中立即停止線程執行/終止

  1. 移動機器人
  2. 停止機器人

機器人需要一些時間來移動從一點到另一點。因此,我調用一個新的線程來控制機器人的運動,以防止GUI無響應。移動功能下方:

from threading import Thread 
from thread import start_new_thread 

def move_robot(self): 
    def move_robot_thread(points): 
     for point in points: 
      thread = Thread(target=self.robot.move, args=(point,)) 
      thread.start() 
      thread.join() 
    start_new_thread(move_robot_thread, (points,)) 

上述功能運行良好。爲了阻止機器人的運動,我需要停止執行上述線程。請參閱下面的完整代碼:

from python_qt_binding.QtGui import QPushButton 

self.move_robot_button = QPushButton('Move Robot') 
self.move_robot_button.clicked.connect(self.move_robot) 
self.move_robot_button = QPushButton('Stop Robot') 
self.move_robot_button.clicked.connect(self.stop_robot) 
self.robot = RobotControllerWrapper() 

from threading import Thread 
from thread import start_new_thread 

def move_robot(self): 
    def move_robot_thread(points): 
     for point in points: 
      thread = Thread(target=self.robot.move, args=(point,)) 
      thread.start() 
      thread.join() 
    start_new_thread(move_robot_thread, (points,)) 

def stop_robot(self): 
    pass 

class RobotControllerWrapper(): 
    def __init__(self): 
     self.robot_controller = RobotController() 

    def move(self, point): 
     while True: 
      self._robot_controller.move(point) 
      current_location = self.robot_controller.location() 
      if current_location - point < 0.0001: 
       break 

如何停止執行線程?有什麼建議嗎?

沙发
0
0

使用標誌應該足夠:

self.run_flag = False # init the flag 
... 

def move_robot(self): 
    def move_robot_thread(points): 
     self.run_flag = True # set to true before starting the thread 
     ... 

def stop_robot(self): 
    self.robot.stop() 

class RobotControllerWrapper(): 
    ... 
    def move(self, point): 
     while self.run_flag == True: # check the flag here, instead of 'while True' 
      ... 

    def stop(self): 
     self.run_flag = False # set to false to stop the thread 
0
votes
answers
44 views
+10

多線程共享本地變量

2

我想充分了解如何創建單獨線程調用一個類實例的同樣的方法可以在該方法實現的局部變量。多線程共享本地變量

例如我有一個單一的方法(劃分)的一類

public class Maths 
{ 
    public int Num1; 
    public int Num2; 

    public void Divide() 
    { 
     for (long i = 0; i < 100000; i++) 
     { 
      Num1 = 2; 
      Num2 = 2; 
      int result = Num1/Num2; 
      Num1 = 0; 
      Num2 = 0; 
     } 
    } 
} 

兩個線程被實例化並稱爲劃分方法如下:

static void Main(string[] args) 
    { 
     Maths m = new Maths(); 

     Task t1 = new Task(() => m.Divide()); 
     Task t2 = new Task(() => m.Divide()); 

     List<Task> tl = new List<Task> { t1, t2 }; 
     Parallel.ForEach(tl, task => task.Start()); 

     Console.ReadLine(); 
    } 

} 

有時,這種代碼運行正常。但是其他時間它將引發就行了dividebyzero錯誤:

INT結果= NUM??1/NUM2;

我的假設是,一個線程被重置NUM1和NUM2零其他線程調用NUM1/NUM2之前。因此造成零除異常。

這將使意義,我應該用一個鎖,但我不明白如何將這些局部變量NUM1和NUM2是在線程之間共享,因爲我的理解是,局部變量不是線程之間共享?

+0

謝謝,現在有道理。 – selams

沙发
0
5

你是正確的,局部變量不是線程(通常,每次方法被調用時,新的一組之間共享它的局部變量執行線程的堆棧中分配的,每個方法調用,這樣局部變量是完全獨立的,並其中一個的修改對其他的沒有影響)。

但是不幸的是Num1Num2不是局部變量,而是fields。同一個類的實例的字段在線程之間共享。

您將需要declate他們這樣讓他們局部變量:

public class Maths 
{ 
    public void Divide() 
    { 
     int Num1; 
     int Num2; 

     for (long i = 0; i < 100000; i++) 
     { 
      Num1 = 2; 
      Num2 = 2; 
      int result = Num1/Num2; 
      Num1 = 0; 
      Num2 = 0; 
     } 
    } 
} 

或者,你coud爲每個線程創建Maths類的單獨的實例,所以每個線程將使用領域Num1和不同Num2Maths類的實例:

static void Main(string[] args) 
{ 
    Maths m1 = new Maths(); 
    Maths m2 = new Maths(); 

    Task t1 = new Task(() => m1.Divide()); 
    Task t2 = new Task(() => m2.Divide()); 

    List<Task> tl = new List<Task> { t1, t2 }; 
    Parallel.ForEach(tl, task => task.Start()); 

    Console.ReadLine(); 
} 
+0

完美的答案和很好的解釋! –

板凳
0
3

由於您使用的是同一個對象,都在同一個任務的更新動作影響其他。

+2

......但只因爲NUM1和NUM2的領域,而不是本地變量,如NUF解釋 –

+0

是,NUF答案更好地解釋它。 – Felipe

0
votes
answers
43 views
+10

FileSystemWatcher的報告可用的文件網絡共享,但文件無法找到

-1

背景FileSystemWatcher的報告可用的文件網絡共享,但文件無法找到

我有了一個共享文件夾\ServerShare有4子文件夾的服務器:

  • OutboundFinal
  • OutboundStaging
  • InboundFinal
  • InboundStaging

所有文件夾駐留在同一個物理磁盤和分區上,不使用連接點。

我也有幾個WinForms客戶端(最多10個)寫和讀文件到這個共享中,每個客戶端在多線程(最多5個)上工作。客戶端文件(最多50個線程)被登錄到\ServerShareOutboundStaging文件夾中。每個文件都有一個GUID的名稱,所以不會覆蓋。文件完成寫入後,客戶端將其移至\ServerShareOutboundFinal文件夾。在同一臺服務器上運行的Windows服務會將其選中,刪除,處理,然後將具有相同名稱的文件寫入\ServerShareInboundStaging文件夾。文件完成寫入後,它將被服務移動到\ServerShareInboundFinal文件夾。

這\服務器共享文件夾InboundFinal通過使用FileSystemWatcher.WaitForChanged(WatcherChangeTypes.Changed | WatcherChangeTypes.Created, timeOut);FileSystemWatcher.Filter每個客戶的WinForms每個線程監視設置爲某線程預計在服務器共享查看該文件的文件名GUID InboundFinal文件夾,因此FileSystemWatcher會一直等到文件夾中顯示特定文件。

我已經閱讀了關於FileSystemWatcher的幾個SO問題,表現不正常並且未報告UNC股份的變化。然而,這不是我的情況。

我使用的代碼如下所示:

FileSystemWatcher fileWatcher = new FileSystemWatcher(); 
    fileWatcher.Path = InboundFinalFolder; 
    fileWatcher.Filter = GUIDFileName; // contains full UNC path AND the file name 
    fileWatcher.EnableRaisingEvents = true; 
    fileWatcher.IncludeSubdirectories = false; 
    var res = fileWatcher.WaitForChanged(WatcherChangeTypes.Changed | WatcherChangeTypes.Created, timeOut); 
    if (!fileWatcher.TimedOut) 
    { 
     using (FileStream stream = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) { 
     byte[] res = new byte[stream.Length]; 
     stream.Read(res, 0, stream.Length); 
     return res; 
    } 

這是使用行拋出異常。

的問題

我將認爲fileWatcher.WaitForChanged將繼續只要用正確的GUID名的文件在\ServerShareInboundFinal文件夾中。這正是FileSystemWatcher在本地文件夾上的工作方式,而不是通過網絡訪問的文件共享(本地文件,甚至通過共享訪問,也傾向於工作)。 FileSystemWatcher報告線程正在等待的文件位於FileSystemWatcher \ServerShareInboundFinal文件夾中。但是,當我嘗試讀取文件時,出現FileNotFoundException。讀取線程必須等待3-15秒才能讀取文件。我嘗試用FileStream與Read共享打開文件。

什麼可能導致此行爲?我如何解決它?理想情況下,FileSystemWatcher.WaitForChanged(WatcherChangeTypes.Changed | WatcherChangeTypes.Created, timeOut);應該只能繼續執行,如果文件可以被讀取或超時發生。

+0

FileNotFoundException是非常基本的。一個標準的錯誤是使用GUIDFileName打開文件。不夠好,這不是一個完整的路徑。測試時意外工作,從不在服務器上工作。也可以嘗試禁用反惡意軟件,以防萬一它認爲在掃描時隱藏文件是個好主意。你沒有發佈實際失敗的代碼,所以這些只是猜測。 –

+0

GUIDFileName屬性包含完整的UNC路徑和GUID文件名。對不起,我編輯了我的問題中的代碼片段來澄清。 – Daniel

+0

這是**使用**行引發異常。 – Daniel

沙发
0
0

的FileSystemWatcher的有一個不好的名聲,但實際上,它並不壞......

1。)

您的代碼示例不能編譯。我試過這個:

FileSystemWatcher fileWatcher = new FileSystemWatcher(); 
fileWatcher.Path = "X:\temp"; 
fileWatcher.Filter = "test.txt"; 
fileWatcher.EnableRaisingEvents = true; 
fileWatcher.IncludeSubdirectories = false; 

var res = fileWatcher.WaitForChanged(WatcherChangeTypes.Changed | 
           WatcherChangeTypes.Created, 20000); 
if (!res.TimedOut) 
{ 
    FileInfo fi = new FileInfo(Path.Combine(fileWatcher.Path, res.Name)); 

    using (FileStream stream = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) 
    { 
     byte[] buf = new byte[stream.Length]; 

     stream.Read(buf, 0, (int)stream.Length); 
    } 

    Console.WriteLine("read ok"); 
} 
else 
{ 
    Console.WriteLine("time out"); 
} 

我測試了這個,其中X:是一個SMB共享。它的工作沒有問題(對我來說,見下文)。

但是:

你應該打開/讀取重試(後,每失敗露宿100毫秒)的文件。這是因爲您可能會遇到FileSystemWatcher檢測到文件但移動(或其他寫入操作)尚未結束的情況,因此您必須等到文件創建/移動器真正準備就緒。

或者您不要等待「真實」文件,而是關閉文件移動任務在關閉「真實」文件後創建的標誌文件。

2)

難道說,此舉任務沒有正確關閉文件?

3)

幾年前,我有一些工具(用Perl編寫),其中一個腳本創建一個標誌文件,另一個腳本等待它。

我在SMB 2份額上遇到了一些令人討厭的問題。我發現這是由於SMB緩存。

https://bogner.sh/2014/10/how-to-disable-smb-client-side-caching/

File open fails initially when trying to open a file located on a win2k8 share but eventually can succeeed

https://technet.microsoft.com/en-us/library/ff686200.aspx

試試這個(在客戶端上):

Windows Registry Editor Version 5.00 

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesLanmanWorkstationParameters] 

"DirectoryCacheLifetime"=dword:00000000 
"FileNotFoundCacheLifetime"=dword:00000000 

保存此作爲disablecache.reg和運行regedit disablecac he.reg

然後重新啓動。

+0

我不知道爲什麼它被投票(我固定),因爲你的答案有很多有用的信息我的情況。事實上,這個答案有許多與我的問題有關的事情。 – Daniel

+0

感謝您的回答。該FileNotFoundCacheLifetime設置似乎只是我需要的。我打開帶有重試次數的文件(重試10次,延遲1000毫秒,因爲它對我來說並不重要),但有時甚至還不夠。我忽略了那部分代碼,因爲它看起來不相關。 – Daniel

0
votes
answers
32 views
+10

如何找到您的失敗的線程標識符?

0

每個帖子混淆Disqus線程ID。必須恢復正確的線程ID。無法通過Disqus管理員面板找到線索標識符。如何找到您的失敗的線程標識符?

+0

*「檢查解決方案的答案」* - 您是否想象別人會這樣做? – jonrsharpe

+0

有很多人可能會流失(也有關於演示文稿,更好的可讀性;有很多人編輯問題來解決問題等,即使它已標記爲已回答)。 但是,嘿;謝謝你指出我的修辭錯誤。祝你有美好的一天。 –

沙发
0
0
  1. 轉到Disqus管理面板。
  2. 由url讓你Disqus論壇簡碼%YOURFORUMNAME%.disqus.com /管理/
  3. 前往Disqus API的應用程序:https://disqus.com/api/applications/
  4. 註冊一個新的應用程序(標籤,說明,組織的網站;輸入您的disqus論壇的主機域名)
  5. 轉到Disqus API控制檯:https://disqus.com/api/console/
  6. 從下拉列表中選擇在論壇類別下的listThreads。
  7. 添加參數:「論壇」和「%YOURFORUMNAME%」,點擊提交。
  8. 複製JSON數據。
  9. 將其獲取到可讀的JSON解析器/轉換器以實現更輕鬆的工作流程。 https://konklone.io/json/
  10. 使用「id」和「clean_title」列輸入您正確的wordpress線程ID。