각 작업을 소비하는 한정된 소비자 스레드 세트가 있습니다. 일단 작업을 처리하면 소모 된 작업에 나열된 하위 작업 목록이 있습니다. 데이터베이스에 아직없는 목록에서 하위 작업을 추가해야합니다. 데이터베이스에 3 백만 개가 있으므로 데이터베이스에없는 목록을 얻는 것이 느립니다. 나는 각 스레드가 해당 호출을 차단하는 것을 신경 쓰지 않지만, 경쟁 조건 (코드 참조)이 있기 때문에 느린 호출에서 모든 코드를 잠궈 야하므로 한 번에 하나씩 만 호출 할 수 있고 프로그램은 크롤링 할 수 있습니다. 이 문제를 해결하기 위해 스레드가 통화를 늦추지 않도록하려면 어떻게해야합니까? 대기열을 시도했지만 컴퓨터가 데이터베이스에 추가해야하는 작업보다 스레드가 작업 목록을 빨리 밀어 내고 있기 때문에 계속 커지고 빈 상태가되지 않는 대기열로 끝납니다.다중 스레드 세트 차이에 대한 효율적인 접근
내 코드 :
IEnumerable<string> getUniqueJobNames(IEnumerable<job> subJobs, int setID)
{
return subJobs.Select(el => el.name)
.Except(db.jobs.Where(el => el.set_ID==setID).Select(el => el.name));
}
//...consumer thread i
lock(lockObj)
{
var uniqueJobNames = getUniqueJobNames(consumedJob.subJobs, consumerSetID);
//if there was a context switch here to some thread i+1
// and that thread found uniqueJobs that also were found in thread i
// then there will be multiple copies of the same job added in the database.
// So I put this section in a lock to prevent that.
saveJobsToDatabase(uniqueJobName, consumerSetID);
}
//continue consumer thread i...
무엇 todo를 시도하고 있습니다, 다시 설명 할 수 있습니까? 수행 할 작업은 무엇입니까? 정보가 없으면 실제 작업이 더 명확 해집니다. – ntziolis
먼저 기존 작업의 목록을 가져온 다음 목록을 컴파일 할 수 없습니까? "새로운"하위 작업을 병행하여 수행하고 마지막으로 새로운 작업을 저장합니까? –
문제는 예외를 사용하여 데이터베이스와 비교하지 않으면 어느 것이 새로운 것인지 알 수 없다는 것입니다. 필자는 모든 하위 작업 목록을 컴파일 할 수 있었지만 마침내 데이터베이스와 비교하기를 원할 때 다음 목록이 나올 때까지 작업을 마칠 수 없었습니다. 그것들은 내가 나중에 목록을 캐싱하거나 즉시 실행할 때 Except 메서드를 실행할 수있는 것보다 빠르게 구축하고 있습니다. 실제로 그것을 즉시 실행하면 소비자가 더 빨리 달리고 이슈가 더 복잡해질 것입니다. 나는 도움이 될 수있는 데이터 구조, 또는 단지 다른 알고리즘을 추측하고 있습니다. – brandon