반응형

출처 : https://stackoverflow.com/questions/3125645/why-use-select-instead-of-sleep

왜 sleep() 대신에 select()를 사용하나요?

저는 iPhone 오디오에 대한 장을 살펴보고 있는데 이해할 수 없는 코드 섹션을 발견했습니다.

while (aqc.playPtr < aqc.sampleLen) 
{
    select(NULL, NULL, NULL, NULL, 1.0);
}

(전체 코드 샘플은 163-166페이지에 있습니다). 코드에 대해 내가 이해한 바에 따르면 오디오가 다른 스레드에서 처리되고 있고 while 루프는 오디오가 여전히 처리되는 동안 메인 스레드가 종료되는 것을 방지하기 위한 것입니다.

제가 이해할 수 없는 것은 왜 select()sleep() 대신에 사용되었는지 입니다.

내가 읽은 것에서 select()는 I/O의 변경 사항을 모니터링하는 데 사용되며 NULL을 전달해도 의미가 없습니다. sleep()을 사용하여 코드를 실행했으며 예상대로 작동합니다. (저수준 POSIX에 대한 나의 지식은 거의 존재하지 않습니다.)


6개의 답변 중 1 개의 답변

정확한 1초 미만 대기 허용을 선택하고 sleep 보다 이식성이 좋습니다. 대기하는 다른 방법이 있는데 이 질문을 참조하십시오.

그러나 select의 timeout 매개변수는 float가 아니라 struct timeval에 대한 포인터여야 합니다. 나는 당신이 보여주는 코드가 심지어 컴파일된다는 것에 놀랐습니다. More : 이 이상한 조건부 선택 다음에 무조건적인 sleep(1)이 뒤따릅니다. 무의미해 보입니다.

반응형
반응형

출처 : https://stackoverflow.com/questions/24720442/selecting-second-child-in-beautiful-soup-with-soup-select

soup.select로 beautiful soup에서 두번째 child 선택하기

다음 태그가 있습니다.

<h2 id='names'>Names</h2>
<p>John</p>
<p>Peter</p>

이제 h2 태그가 이미 있으면 Peter를 얻기 위한 이제 가장 쉬운 방법은 무엇입니까? 다음을 시도하였습니다.

soup.select("#names > p:nth-child(1)")

여기에 nth-child에서 NotImplementedError: 오류가 발생하였습니다.

NotImplementedError: Only the following pseudo-classes are implemented: nth-of-type.

그래서 나는 여기서 무슨 일이 일어나고 있는지 잘 모르겠습니다. 두 번째 방법은 모든 'p' 태그 자식들을 얻어 직접 [1]을 선택하는 것이지만 조금 무식한 try/except 구문으로 Peter를 얻기 위해 전부 시도하는 것을 요구하여 out of range 인덱스 오류의 위험이 있습니다.

soup.select() 함수로 nth-child를 선택하는 방법이 있습니까?

편집:: 트릭같지만 nth-of-type로 nth-child를 대체합니다. 수정한 내용은:

soup.select("#names > p:nth-of-type(1)")

nth-child를 받아들이지 않는 이유가 확실하지 않지만 nth-child와 nth-of-type는 같은 결과를 리턴하는 거 같습니다.

2개의 답변 중 1개의 답변만 추려냄

다른 사람이 더 쉽게 찾을 수 있도록 수정 사항을 답변으로 추가 :

nth-of-type 대신에 nth-child를 사용합니다.

soup.select("#names > p:nth-of-type(1)")
반응형
반응형

출처 :https://stackoverflow.com/questions/2472229/insert-into-select-from-on-duplicate-key-update

INSERT INTO … SELECT FROM … ON DUPLICATE KEY UPDATE

저는 만약 키가 이미 있을 경우 대부분의 많은 컬럼이 갱신될 필요가 있는 insert 쿼리를 실행하려 합니다.
다음처럼 진행하려 하는데요.

INSERT INTO lee(exp_id, created_by, 
                location, animal, 
                starttime, endtime, entct, 
                inact, inadur, inadist, 
                smlct, smldur, smldist, 
                larct, lardur, lardist, 
                emptyct, emptydur)
SELECT id, uid, t.location, t.animal, t.starttime, t.endtime, t.entct, 
       t.inact, t.inadur, t.inadist, 
       t.smlct, t.smldur, t.smldist, 
       t.larct, t.lardur, t.lardist, 
       t.emptyct, t.emptydur 
FROM tmp t WHERE uid=x
ON DUPLICATE KEY UPDATE ...; 
//update all fields to values from SELECT, 
//       except for exp_id, created_by, location, animal, 
//       starttime, endtime

저는 UPDATE 구문을 위한 문법에 무엇이 와야 되는지 확실하지 않습니다. SELECT 구문으로부터 현재 행을 어떻게 참조할 수 있을까요?

2개의 답변 중 1개의 답변만 추려냄

MySQL은 INSERT INTO 구문에서 등호 앞에 부분이 컬럼(필드)명을 참조하고 SELECT 컬럼(필드)를 등호 뒤에 두번째 부분에서 참조한다고 가정합니다.

INSERT INTO lee(exp_id, created_by, location, animal, starttime, endtime, entct, 
                inact, inadur, inadist, 
                smlct, smldur, smldist, 
                larct, lardur, lardist, 
                emptyct, emptydur)
SELECT id, uid, t.location, t.animal, t.starttime, t.endtime, t.entct, 
       t.inact, t.inadur, t.inadist, 
       t.smlct, t.smldur, t.smldist, 
       t.larct, t.lardur, t.lardist, 
       t.emptyct, t.emptydur 
FROM tmp t WHERE uid=x
ON DUPLICATE KEY UPDATE entct=t.entct, inact=t.inact, ...

2개의 팁 추가 번역

  • @dnagirl: : PK 컬럼중 어느것도 update하지 마세요. 리스트에서 갱신할 필요가 있는 것만 update하세요.
  • 당신이 제안한 문법은 작동하며 t.가 요구됩니다. 저는 xaprb의 블로그글(xaprb.com/blog/2006/02/21/flexible-insert-and-update-in-mysql)에서 이 문법 on duplicate key update b = values(b), c = values(c)을 보았습니다. 이것도 작동합니다.
반응형
반응형

12-1. I/O 멀티플렉싱 기반의 서버

하나의 전송로를 여러 사용자가 동시에 사용해서 효율성을 극대화 하는 것. 전송로를 공유.

전송로를 공유하기 위해서는 서로 약속이 필요하다.

TDMA : 자료 전송 시간을 일정한 시간 폭으로 나누어서 함께 공유하는 방식

FDMA : 주파수 대역 폭을 나누어서 함께 공유하는 방식


I/O 멀티플렉싱

클라이언트와의 입/출력을 담당하는 프로세스를 하나로 묶어버리는 것.

프로세스 = 고속의 전송로.


multitasking(멀티태스킹) 예시


multiplexing(멀티플렉싱) 예시

※ 데이터 입출력 및 접속 모두를 하나로 묶어서 처리한다.

※ 멀티플렉싱 서버가 멀티태스킹 서버보다 성능이 좋다. -> context switching이 없음.


멀티 프로세스 vs 멀티 플렉싱

멀티 프로세스

클라이언트와 서버간의 송수신 데이터 용량이 큰 경우.

송수신이 연속적으로 발생하는 경우에 적합.

멀티 플렉싱

클라이언트와 서버간의 송수신 데이터 용량이 작은 경우.

송수신이 연속적이지 않은 경우에 적합. (예: 채팅)

멀티 프로세스 기반의 서버에 비해 많은 수의 클라이언트 처리에 접함.


12-2. Select 함수 사용하기

파일 디스크립터의 설정

지정된 파일 디스크립터의 변화를 확인한다.

파일 디스크립터 변화 : 파일 디스크립터를 통해 데이터 송수신이 가능한 상태

예시)


1. 파일 디스크립터 설정

관찰하고자 하는 파일 디스크립터를 모아놓는다. (총 3묶음)

2. 파일 디스크립터의 변화(3가지 종류 존재)

입력 버퍼의 변화 : 수신할 데이터가 존재하는가? (입력 버퍼에 데이터 존재)

출력 버퍼의 변화 : 데이터 전송이 가능한 상태인가? (출력 버퍼에 충분한 여유공간 존재)

예외(OOB)상황 관련 버퍼의 변화 : 소켓에서 예외상황이 발생 하였는가?

3. fd_set 자료형

파일 디스크립터를 구분 지어 모아두기 위한 자료형(비트단위 배열)


파일 디스크립터 검사 범위 설정
매크로 함수

FD_ISSET(int fd, fd_set *fdset);
fdset에서 해당 fd(번호)의 비트가 1인지 확인한다. 1이면 TRUE, 0이면 FALSE.

검사해야 할 파일 디스크립터의 개수(범위)를 지정해 준다.

(select 마지막에 리턴된 디스크립터 값에) 가장 큰 파일 디스크립터 값에 1을 더해서 인자를 전달.


Timeout(타임아웃) 설정

Timeout : 정해 놓은 시간이 지나면 (select)함수가 리턴하게 한다.
struct timeval
{
    long tv_sec;    // 초단위
    long tv_usec;  // 마이크로초단위 1/10^6
};

select함수
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>

int select(int n, fd_set * readfds, fd_set *writefds, fd_set * exceptfds,struct timeval * timeout);
리턴 : 오류 발생이면 -1, 타임아웃이면 0, 변화가 발생하면 0이 상에 상태가 바뀐 파일 디스크립터 수.
n : 파일 디스크립터 개수(범위) 지정.
readfds : 입력버퍼(수신)할 데이터가 있는지 검사.
writefds : 출력버퍼가 충분히 여유가 있는지 검사.
exceptfds : OOB에 대한 검사. ※ 추후설명
timeout : 타임아웃 설정관련 인수.


select함수를 호출하기 전에는 fd_set에 검사하기 원하는 index의 비트를 1로 세팅해 놓는다.
예시) FD_SET(0, &read_s);    // standard input에 대한 디스크립터를 1로 세팅.
select함수가 리턴이 되면 fd_set에 검사한 결과에 대한 index의 비트만이 1로 세팅되어 있을 것이다.
※ select함수 호출 전과 호출 후에 값이 바뀌기 때문에 select함수를 호출할 때마다 초기화할 수 있도록 원본 fd_set을 복사하여 사용한다.
※ timeout도 select함수 호출 전과 호출 후에 값이 바뀌기 때문에 루프 시작할 때 값을 새로 초기화 주는 것이 좋다.

12-3. 멀티플렉싱 서버의 구현
FD_SET(serv_sock, &reads);
※ 서버소켓으로 오는 입력버퍼(데이터)의 내용이 중요하다. 그 내용은 클라이언트로부터 들어오는 연결요청(일종의 데이터이기 때문)이다.
fd_max : 검사할 디스크립터 개수(범위)를 저장하기 위한 값. 0~fd_max+1의 범위로 설정한다.

12-4. 윈도우즈 기반으로 구현하기
select 함수와 timeval 구조체는 선언된 형태와 기능이 리눅스와 같다.
int select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout);

※ fd_set 자료형은 기능이 리눅스와 같지만 선언형태는 다르다.
typedef struct fd_set{
    u_int fd_count;                                 // 얼마나 많이 설정되어 있는가?
    SOCKET fd_array[FD_SETSIZE];      // SOCKET의 배열
}fd_set;
※ 소켓의 핸들 값이 일정하지 않고 윈도우즈에는 리턴된 핸들 값을 기억하는 것이 편하다.
그러므로 소켓 핸들의 개수를 fd_set 내부적으로 보관하고 있다.


※ 다음 매크로는 리눅스와 사용 방법은 거의 같다.
FD_CLR(s, *set)
:set 포인터가 가리키는 배열에서 핸들 s를 삭제한다.
FD_ISSET(s, *set)
:핸들 s가 set포인터가 가리키는 배열의 멤버라면 TRUE를 아니면 FALSE를 리턴한다.
FD_SET(s, *set)
:핸들 s를 set포인터가 가리키는 배열의 멤버에 포함시킨다.
FD_ZERO(*set)
:set 포인터가 가리키는 배열을 0으로 초기화한다. 

select(0, &temps, 0, 0, &timeout)
※ 윈도우즈 기반에서는 nfds인수가 필요없다.

반응형

+ Recent posts