我有这份作业要送到学校 - 我已完成并发送并获得 0% :] ... 所以想请问我的想法是否正确。例如,如果我想用线程编写程序 - 我必须调用 50 次 thrfunction 并且我有 5 个可用线程(并且我必须尽可能多地使用它们)。你能告诉我我是否做错了什么 - 我想我是因为 printf 说我只使用一个线程?我不太确定我会用什么方法来做这件事。
提前致谢 尼古拉斯·吉萨
这是我的源代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define THREADS 5
#define CYCLES 50
sem_t sem1;
pthread_mutex_t m1, m2;
long int result = 0;
int thread_status[THREADS]; // status of threads, value -1 for working thread, other values for free threads
typedef struct Arg {
long int number;
int thread_ID; } ARG;
void * thrfunction ( void * arg ) {
int number = (( ARG * ) arg)->number, thread_ID = (( ARG * ) arg)->thread_ID, i;
thread_status[thread_ID] = -1;
pthread_mutex_unlock ( & m1 );
for ( i = 0; i < number; i ++ );
pthread_mutex_lock ( & m2 );
result = result + number;
printf ( "Thread %d result = %ld\n", thread_ID, result );
pthread_mutex_unlock ( & m2 );
pthread_mutex_lock ( & m1 );
thread_status[thread_ID] = thread_ID;
sem_post ( & sem1 );
pthread_mutex_unlock ( & m1 );
return NULL; }
int main ( int argc, char * argv[] ) {
pthread_t thr[THREADS];
pthread_attr_t Attr; pthread_attr_init ( & Attr ); pthread_attr_setdetachstate ( & Attr, PTHREAD_CREATE_JOINABLE );
pthread_mutex_init ( & m1, NULL ); pthread_mutex_init ( & m2, NULL );
sem_init ( & sem1, 0, THREADS );
int i, j;
ARG * pom = ( ARG * ) malloc ( sizeof ( * pom ) );
for ( i = 0; i < THREADS; i ++ )
thread_status[i] = i;
for ( i = 0; i < CYCLES; i ++ ) {
pom->number = rand () % 100000 * 10000;
sem_wait ( & sem1 );
pthread_mutex_lock ( & m1 );
for ( j = 0 ; j == -1; j ++ );
pthread_create ( & thr[j], & Attr, thrfunction, ( void * ) pom ); }
free ( pom );
pthread_attr_destroy ( & Attr ); pthread_mutex_destroy ( & m1 ); pthread_mutex_destroy ( & m2 ); sem_destroy ( & sem1 );
for ( i = 0; i < THREADS; i ++ )
pthread_join ( thr[i], NULL );
return 0;}
最佳答案
我发现的第一个问题是您使用锁过于频繁。
如果程序所做的只是获取锁,那么线程编程的效率要比顺序编程低得多。获取和释放锁需要时间。您的程序应该做的工作就被占用了这些时间。
我看到的第二个问题是 thrfunction
中的 for
循环什么也不做。它从 0 到数字计数 i 吗?这就是它的全部作用吗?
我看到的第三个问题是您调用 free(pom)
并在创建所有线程后调用 pthread_mutex_destroy
。 不好!线程仍在使用它!您无法保证线程此时已经开始运行。您的操作系统可能需要几秒钟甚至几分钟(如果 RAM 不足并交换到磁盘)才能开始运行您创建的所有线程。
对于考虑线程,您可能会发现有用的方法是写下每个“关键部分”,即锁之间的部分、卡片上或使用任何可移动的东西来表示这些部分。为每个线程制作一列这些卡片或碎片。这些片段可以在时间轴上向上或向下移动任何位置,除非锁、连接、信号量或其他任何东西阻止它。如果您想获得真正的技术,编译器优化和处理器乱序执行甚至可以在限制范围内重新排列各个部分的执行顺序。
某些程序(不是您的)可能如下所示(并查看线程如何在步骤 7 中的锁定处减慢至单一速度):
0 <- parent process spawns threads
1 <- parent process calls join to wait for thread in first column.
2 2 2
3 3
4 3 4
5 5 2
6 6 3
4
5
6
7 4 7 7 <-- step 7 waits for lock
5 8
6 9
7 10
11 <- step 11 releases lock
8
9
10
11
8
9
10
11
8
9
10
11
12 12 12 12
13 13 13 13
14 14 14 14 <- step 14 each thread returns.
15 <- parent process wait on thread 1 succeeds.
16 <- wait for thread 2
17 <- wait for thread 3
18 <- wait for thread 4
19 <- parent now cleans up thread data, lock data.
20 <- parent exits.
关于c - POSIX - 信号量、互斥体、线程 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5438251/