C pthread只允许四个线程执行函数

时间:2016-06-02 08:36:18

标签: c concurrency pthreads semaphore

这是一个问题,比如说我需要执行一次x次函数来执行某些操作,但只有四个线程可以在任何给定时间执行它。因此,线程A,B,C,D可以分别启动任务0,1,2,3。但是,任务4在其中一个线程完成之前无法启动,因此如果线程A完成,那么下一个任务可以由其中一个空闲线程执行。这应该重复x次,其中x是需要调用函数的次数。

所以我使用信号量并在完成后加入pthread以确保它完成。但是,有时主函数在某些线程完成之前完成执行,而valgrind抱怨我的pthread_create正在泄漏内存。我认为我正在做的方式不正确或是天真方法,所以任何指导或示例代码来解决这个问题都将非常受欢迎!这是我的代码:

public class MainActivity extends Activity implements OnMapReadyCallback {

private GoogleMap googleMap;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap map) {

googleMap = map;

setUpMap();

}
public void setUpMap(){
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.setMyLocationEnabled(true);
googleMap.setTrafficEnabled(true);
googleMap.setIndoorEnabled(true);
googleMap.setBuildingsEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
}

非常感谢

2 个答案:

答案 0 :(得分:1)

让线程彼此等待通常会很快变得混乱,而且你可能最终会遇到线程试图加入自身或者从未加入的情况。

最多运行四个线程的最可靠方法是只创建四个线程 您可以让每个线程(可能)执行多个任务,而不是根据需要创建线程。

您可以分离"任务"来自"线程的概念"概念:

  • 为要执行的线程创建任务队列。
  • 创建四个主题。
  • 每个线程从队列中获取任务并执行它,重复直到队列为空。
  • 等待线程在main中完成。

唯一需要同步的是从队列中删除任务,这非常简单 (如果任务不是独立的,则需要更复杂的管道。)

Pseudocode(我发明了一些名字,因为我对pthreads并不太熟悉):

typedef struct Task
{
    /* whatever */  
};

/* Very simplistic queue structure. */
typedef struct Queue
{
    mutex lock;
    int head;
    Task tasks[num_tasks];
};

/* Return front of queue; NULL if empty. */
Task* dequeue(Queue* q)
{
    Task* t = NULL;
    lock_mutex(q->lock);
    if (q->head < num_tasks)
    {
        t = &q->tasks[q->head];
        q->head++;
    }
    unlock_mutex(q->lock);
    return t;
}

/* The thread function is completely unaware of any multithreading
   and can be used in a single-threaded program while debugging. */ 
void* process(void* arg)
{
    Queue* queue = (Queue*) arg;
    for (;;)
    {
        Task* t = dequeue(queue);
        if (!t)
        {
            /* Done. */
            return NULL;
        }
        /* Perform task t */
    }
}

/* main is very simple - set up tasks, launch threads, wait for threads.
   No signalling, no memory allocation. */
int main(void)
{
    pthread threads[num_threads];
    Queue q;
    q.head = 0;
    /* Fill in q.tasks... */
    /* Initialise q.lock... */

    for (int ti = 0; ti < num_threads; ti++)
    {
        pthread_create(threads + ti, NULL, process, &q);
    }
    for (int ti = 0; ti < num_threads; ti++)
    {
        /* join the thread */
    }

    return 0;
}

答案 1 :(得分:0)

您的代码一次启动四个线程并等待它们完成。但是,您的主循环只创建线程,它们不会退出。 创建线程后,您的操作系统会随时调整它。

这意味着你必须加入你在for循环后创建的最后四个线程。所以他们有机会完成工作并释放他们的记忆。

问候