使用Pthreads在C中为学校项目工作,将一维数组分解为tRows和tCols的子矩阵。整个数组的大小为wRows和wCols。让我们说wCols = 4,wRows = 4,tCols = 2,tRows = 2.如果数组的输入是整数1-16,我们将得到以下网格:
1 2 3 4
5 6 7 8
9 10 11 12
1314 15 17
Thus Thread 0 would process the subgrid
1 2
5 6
Thread 1
3 4
7 8
Thread 2
9 10
13 14
Thread 3
11 12
15 17
如何使用两个for循环迭代一维数组以获取基于使用哪个Thread的值? 我觉得我需要计算两个线程的开始和结束,但我完全坚持这个。
任何帮助将不胜感激。
答案 0 :(得分:1)
pthread_create()
的第四个参数被转发给线程启动函数作为其参数。这样做的目的是将任何必要的特定于线程的数据传递给线程,例如,矩阵补丁的起始行和列。
在这种情况下,向每个线程传递指向其矩阵补丁的最顶部,最左边元素的指针会特别干净。假设每个线程都知道补丁的大小和矩阵中的列数,这足以确定行号和列号。
答案 1 :(得分:0)
这就是我做的方式(它确实利用了第四个参数,如第一个答案中所述):
- (void)main {
for (NSInteger index = 0; index < AppDelegate.sharedAppDelegate.getAssetCount; index++) {
dispatch_queue_t threadQueue = dispatch_queue_create([[NSString stringWithFormat:@"threadQueue %ld", index] UTF8String], DISPATCH_QUEUE_CONCURRENT);
dispatch_async(threadQueue, ^{
pthread_t thread_tid;
pthread_attr_t attr;
int returnVal;
// init and check if init a new thread successful
returnVal = pthread_attr_init(&attr);
assert(!returnVal);
// set attribute detach state for new thread
returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
assert(!returnVal);
// create and run the new thread
int threadError = pthread_create_from_mach_thread(&thread_tid, &attr, &ThreadMethod, (void*)index);
returnVal = pthread_attr_destroy(&attr);
assert(!returnVal);
if (threadError != 0)
{
NSLog(@"Thread error: %i", threadError);
// Report an error.
}
});
//NSLog(@"index: %ld", index);
index = index + 4;
}
}
void* ThreadMethod(void *arg)
{
for (NSInteger loop = 0; loop < 4. ; loop++) {
NSInteger index = (NSInteger)arg + loop;
NSLog(@"index: %ld", index);
[AppDelegate.sharedAppDelegate.imageManager requestAVAssetForVideo:AppDelegate.sharedAppDelegate.assetsFetchResults[(NSInteger)index] options:AppDelegate.sharedAppDelegate.videoOptions resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
if(![[info objectForKey:PHImageResultIsInCloudKey] boolValue]) {
if (asset) {
NSError __autoreleasing *error = nil;
AVAssetReader *reader;
[reader = [AVAssetReader assetReaderWithAsset:asset error:&error] addOutput:[AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] outputSettings:@{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA), (id)kCVPixelBufferWidthKey : @([[UIScreen mainScreen] bounds].size.width / (int)floor(sqrt([AppDelegate.sharedAppDelegate getAssetCount]))), (id)kCVPixelBufferHeightKey : @(([[UIScreen mainScreen] bounds].size.width / (int)floor(sqrt([AppDelegate.sharedAppDelegate getAssetCount]))) * (9.0/16.0))}]];
[reader startReading];
while ([reader status] != AVAssetReaderStatusReading) { }
if ([reader status] == AVAssetReaderStatusReading) { NSLog(@"reader %ld reading", index); }
else { NSLog(@"reader %ld NOT reading", index); }
DisplayLayer *displayLayer = (DisplayLayer *)[[AppDelegate.sharedAppDelegate consumers] objectForKey:[NSString stringWithFormat:@"%ld", (NSInteger)index]];
dispatch_queue_t readerQueue = dispatch_queue_create([[NSString stringWithFormat:@"readerQueue %ld", (NSInteger)index] UTF8String], DISPATCH_QUEUE_SERIAL);
[displayLayer requestMediaDataWhenReadyOnQueue:readerQueue usingBlock:^{
@autoreleasepool {
if ([reader status] == AVAssetReaderStatusReading) {
CMSampleBufferRef sampleBuffer = [[[reader outputs] firstObject] copyNextSampleBuffer];
if (sampleBuffer) {
[displayLayer enqueueSampleBuffer:sampleBuffer];
/*OSStatus err = CMSimpleQueueEnqueue(displayLayer.simpleBuffer, sampleBuffer);
if (err) {
NSLog(@"Producer %ld buffer error: %d", index, (int)err);
CMSimpleQueueReset(displayLayer.simpleBuffer);
}*/
CFRelease(sampleBuffer);
sampleBuffer = nil;
}
}
}
}];
}
}
}];
}
return NULL;
}