【问题标题】:POSIX - semaphores, mutexes, threads CPOSIX - 信号量、互斥体、线程 C
【发布时间】:2011-03-25 21:19:36
【问题描述】:

我有这个作业要上学 - 我完成了它并发送它并得到 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;}

【问题讨论】:

  • 你对下面的代码有信心吗? "for ( j = 0 ; j == -1; j ++ ); pthread_create ( & thr[j], & Attr, thrfunction, ( void * ) pom );"
  • 是的,我想是的......但我对这个 POSIX 编程非常陌生......
  • 好点 Srikanth。尼古拉斯,你期望多少次 (j = 0 ; j == -1; j ++ );运行,你期望它做什么?如果它是一个时序循环,这是一个非常糟糕的主意。如果 C 编译器愿意,它可以完全删除该循环。
  • 或者,如果您在 64 位系统上编译,您的程序可能永远无法完成。
  • I 除了之后 ( j = 0 ; j == -1; j ++ ); “j”将是第一个空闲线程的标识符

标签: c pthreads


【解决方案1】:

我看到的第一个问题是您使用锁过于频繁

如果您的程序所做的只是锁定,那么线程的效率要比顺序编程低得多。锁定需要时间来获取和释放。这段时间从你的程序应该做的工作中消失了。

我看到的第二个问题是thrfunction 中的for 循环什么都不做。它把 i 从 0 算到数字?仅此而已?

我看到的第三个问题是您调用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.

【讨论】:

    猜你喜欢
    • 2011-04-10
    • 2012-04-27
    • 2014-03-01
    • 2017-08-24
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2011-04-20
    相关资源
    最近更新 更多